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

+3


source to share


4 answers


Try:



Data2 = _.Data2 == null ? null : new Data2Model
{
    Id = _.Data2.Id,
    Name = _.Data2.Name,
    Date = _.Data2.Date
},

      

+3


source


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.

+1


source


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.

+1


source


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();

      

0


source







All Articles