Ivan-Mark Debono
Ivan-Mark Debono

Reputation: 16310

Left Outer Join using DefaultIfEmpty throws NullReferenceException

I have 3 lists (reports, userPrinters, allPrinters) which I join together using LINQ. reports contains a list of reports, userPrinters contains the user's preferred printer name and paper source for each report (might be empty or not one-to-one with the reports list) and allPrinters is a list of printers on the system (might not have the same printers as the user's printers).

So my query is:

var list = (from r in reports
    join u in userPrinters on r.Id equals u.ReportId into up
    from userPrinter in up.DefaultIfEmpty()
    join p in allPrinters on userPrinter.PrinterName equals p.Name into ps
    from printer in ps.DefaultIfEmpty()
    select new PrinterSelection() {
        Report = r,
        Printer = printer,                 
        Source = (from s in printer.Sources
           where s.Type == userPrinter.PaperSource
           select s).FirstOrDefault()
       }).ToList();

So with the above query, I get all the reports, left outer join the user's printers and then left outer join all printers.

However, when I include the 2nd left outer join, I get a NullReferenceException.

Should DefaultIfEmpty return a default singleton? What am I missing?

Upvotes: 0

Views: 246

Answers (2)

Ivan-Mark Debono
Ivan-Mark Debono

Reputation: 16310

Thanks to @lakobski's comment. I missed the constructor with the default value. So this is the updated LINQ that works:

var list = (from r in reports
    join u in userPrinters on r.Id equals u.ReportId into up
    from userPrinter in up.DefaultIfEmpty(new UserPrinter())
    join p in allPrinters on userPrinter.PrinterName equals p.Name into ps
    from printer in ps.DefaultIfEmpty(new Printer())
    select new PrinterSelection() {
        Report = r,
        Printer = printer,                 
        Source = (from s in printer.Sources
           where s.Type == userPrinter.PaperSource
           select s).FirstOrDefault()
       }).ToList();

Upvotes: 1

Prajapati Vikas
Prajapati Vikas

Reputation: 300

you have to do null check for userprinter variable like below,

join p in allPrinters on (userPrinter== null ? "no-value" : userPrinter.PrinterName) equals 
p.Name

Upvotes: 0

Related Questions