0

When i am making left join i have this error. How to prevent error if id's doenot intersect?

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.

class Program
{
    static void Main(string[] args)
    {
        List<Component> firstlist = new List<Component>();
        List<Component> secondlist = new List<Component>();
        firstlist.Add(new Component { id = 1, Name = "Jhon" });
        secondlist.Add(new Component { id = 2, Name = "Jhon" });

        var test = from d in firstlist
                                 join i in secondlist
                                 on d.id equals i.id
                                 into a
                                 from b in a.DefaultIfEmpty()
                                 select new Component { id = b.id, Name = b.Name };
        List<Component> Result = test.ToList();
    }

    public class Component
    {
        public int id { get; set; }

        public string Name { get; set; }
    }
}
A191919
  • 3,223
  • 5
  • 29
  • 76
  • 2
    Possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – rory.ap Mar 17 '16 at 16:37
  • 1
    Is it caused by `b`? You may want to check if `b` is not `null` – Ian Mar 17 '16 at 16:41
  • Yes it cause by b. Hot to fix it in linq? – A191919 Mar 17 '16 at 16:47
  • Either add a `where b != null` or really don't do a left join since you only pull values from the right. Really it depends on what you expect, an empty list or a list that contains `null` items or `Component`s with default values. – juharr Mar 17 '16 at 16:49

3 Answers3

3

Try something like the following:

class Program
{
    static void Main(string[] args)
    {
        List<Component> firstlist = new List<Component>();
        List<Component> secondlist = new List<Component>();
        firstlist.Add(new Component { id = 1, Name = "Jhon" });
        secondlist.Add(new Component { id = 2, Name = "Jhon" });

        var test = from d in firstlist
                                 join i in secondlist
                                 on d.id equals i.id
                                 into a
                                 from b in a.DefaultIfEmpty()
                                 select new Component { id = (b != null) ?b.id : default(int), Name = (b != null) ? b.Name : default(string) };
        List<Component> Result = test.ToList();
    }

    public class Component
    {
        public int id { get; set; }

        public string Name { get; set; }
    }
}

As you can see, I added a null check on b before setting it.

select new Component { id = (b != null) ? b.id : default(int), Name = (b != null) ? b.Name : default(string) };

You might also be able to do something like

select (b == null) ? default(Component) : new Component { id = b.id, Name = b.Name };

I'm not 100% sure about the syntax for that second option, but something like that might work.

Ayo I
  • 6,642
  • 4
  • 24
  • 37
1

To fix it, you need to ensure that b is not null before you call/use its method/property/field. Change this:

select new Component { id = b.id, Name = b.Name };

into:

select new Component { id = b == null ? 0 : b.id, Name = b == null ? null : b.Name };

In C#6, you could use null conditional operator ?.:

select new Component { id = b?.id ?? 0, Name = b?.Name };
Ian
  • 28,526
  • 18
  • 60
  • 94
  • the `id = b?.id` will not work because `id` is an `int` and `b?.id` would return an `int?`. So you really need something like `id = b?.id ?? 0`. – juharr Mar 17 '16 at 17:00
  • @juharr you are right, thanks for the correction. `id` is `int` – Ian Mar 17 '16 at 17:01
0

you problem lies in

select new Component { id = b.id, Name = b.Name };

using a.DefaultIfEmpty() can return NULL, and so b.id will throw exception. Correct code should be:

select new Component { id = b==null?return_safe_value:b.id, Name =b==null?rturn_safe_value:b.Name };
TSungur
  • 386
  • 2
  • 9