Handling null nested values ββwhen using .select () in Lambda with Entity Framework
We are having a hard time finding a better way to handle this by declaring a loop after receiving the data.
For example, take this piece of code: (Data2 is bound to Data with foreign key)
context.Data.Select(_ => new DataModel
{
Id = _.Id,
Data2 = new Data2Model
{
Id = _.Data2.Id,
Name = _.Data2.Name,
Date = _.Data2.Date
},
Date = _.Date
});
If _.Data2 is not null it does the right thing, but if _.Data2 is null it will result in an error. Now we are going to add Data2Id to our DataModel and then loop through all records to get the information if it is not null.
var lst = context.Data.Select(_ => new DataModel
{
Id = _.Id,
Data2Id = _.Data2ID
Date = _.Date
}).ToList();
foreach(var item in lst)
{
if (item.Data2Id != null)
{
var dataItem = context.Data2.FirstOrDefault(_ => _.Id == item.Data2Id);
item.Data2 = new Data2Model
{
Id = dataItem.Id,
Name = dataItem.Name,
Date = dataItem.Date
}
}
}
Is there a cleaner / better way to keep this in the original selection loop.
thank
source to share
You can extract the logic in a separate method to shorten your LINQ query and potentially reuse your code:
private static DataModel Map(DataModel _)
{
Data2Model model = _.Data2 ?? new Data2Model();
return new DataModel
{
Id = _.Id,
Date = _.Date,
Data2 = new Data2Model
{
Id = model.Id,
Name = model.Name,
Date = model.Date
}
};
}
Your request will look like this:
context.Data.Select(Map);
You must replace the artificial types with your own.
source to share
context.Data.Select(_ => new DataModel
{
Id = _.Id,
Data2 = _.Data2 == null ?
new Data2Model{Id = _.Data2ID} :
new Data2Model{ Id=_.Data2.Id, Name=_.Data2.Name, Data=_.Data2.Date},
Date = _.Date
});
I am making the assumption that if it is zero do you still have the _Data2ID at hand?
Using ternary operator
If Data2 - null
then return a new one Data2Model
only with a different value_.Data2ID
If it isn't null
, then go ahead and create a new one Data2Model
with all the details.
source to share
You are actually looking for a left join and I would use the power of expressions here:
var data2Collection = from d2 in context.Data2
select new
Data2Model
{
Id = d2.Id,
Name = d2.Name,
Date = d2.Date
};
var lst = (from d1 in context.Data
join d2 in data2Collection on d1.Data2Id equals d2.Id into leftJoin
from d2 in leftJoin.DefaultIfEmpty()
select new DataModel
{
Id = d1.Id,
Data2 = d2,
Date = d1.Date
}).ToList();
source to share