Here is a left join of two tables. On the line g.rpt.Location
in the group by, g.rpt
could be null, so I'm getting warned about dereferencing a possible null object. ctx is a code first Entity Frameworks database.
var query = ctx.ObjTable
.GroupJoin(ctx.RptTable, obj => obj.Upc,
rpt => rpt.Upc,
(obj, rpt) => new { obj, rpt })
.SelectMany(j => j.rpt.DefaultIfEmpty(), (j, rpt) => new
{
j.obj, rpt,
})
.GroupBy(g => new
{
g.rpt.Location, //Problem here
g.obj.Category,
g.obj.Desc,
}
.Select(s => new MyClass
{
Location = s.Key.Location,
Category = s.Key.Category,
Desc = s.Key.Desc,
Total = s.Sum(x => x.rpt.Numeric),
});
I tried g.rpt?.Location
but that gives "An expression tree lambda may not contain a null propagating operator."
tried g.rpt == null ? null : g.rpt
. Tried using ??.
Tried this, seemed far fetched but I tried...
.GroupBy(g => g.rpt == null
? new
{
g.rpt.Location,
g.obj.Category,
g.obj.Desc,
}
: new
{
g.obj.Category,
g.obj.Descriptor,
})
CodePudding user response:
You can provide your own default value in DefaultOrEmpty
, e.g.
var defaultRpt = new Rpt {Location = "", Numeric = 0}
...
.SelectMany(j => j.rpt.DefaultIfEmpty(defaultRpt), (j, rpt)
CodePudding user response:
This worked, thanks to Mike Mozhaaev's comment. Extract the values needed for the further operations in the SelectMany.
I wish I could choose two correct answers because the other answer he provided works too.
var query = ctx.ObjTable
.GroupJoin(ctx.RptTable, obj => obj.Upc,
rpt => rpt.Upc,
(obj, rpt) => new { obj, rpt })
.SelectMany(j => j.rpt.DefaultIfEmpty(), (j, rpt) => new
{
j.obj,
Upc = rpt != null ? rpt.Upc : string.Empty,
Numeric = rpt != null ? (int?)rpt.Numeric : null;
})
.GroupBy(g => new
{
g.Location, //Problem here
g.obj.Category,
g.obj.Desc,
}
.Select(s => new MyClass
{
Location = s.Key.Location,
Category = s.Key.Category,
Desc = s.Key.Desc,
Total = s.Sum(x => x.Numeric),
});