在使用实体框架的Lambda中使用.Select()时处理空嵌套值

时间:2017-06-20 21:12:02

标签: c# entity-framework lambda

我们很难通过在获取数据后声明循环来找出解决此问题的最佳方法。

例如,取这段代码:( Data2与外键绑定数据)

context.Data.Select(_ => new DataModel
                    {
                        Id = _.Id,
                        Data2 = new Data2Model
                        {
                            Id = _.Data2.Id,
                            Name = _.Data2.Name,
                            Date = _.Data2.Date
                        },
                        Date = _.Date                                           
                     });

如果_.Data2不为null,则此操作正确,但如果_.Data2恰好为null,则会出错。我们现在解决这个问题的方法是将Data2Id添加到我们的DataModel中,然后循环遍历所有记录以获取非空的信息。

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
         }
      }
}

是否有更清洁/更好的方法将其保留在原始选择循环中。

由于

4 个答案:

答案 0 :(得分:3)

尝试:

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

答案 1 :(得分:1)

您可以使用单独的方法提取逻辑,以缩短LINQ查询并可能重用代码:

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
        }
    };
}

您的查询而不是:

context.Data.Select(Map);

您应该用自己的类型替换人工类型。

答案 2 :(得分:1)

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

我假设如果它为null,你手边还有_.Data2ID吗?

使用ternary operator

如果Data2为null,则返回一个新的Data2Model,只包含其他_.Data2ID

如果不是null,请继续创建一个包含所有详细信息的新Data2Model

答案 3 :(得分:0)

您实际上正在寻找左连接,我会利用表达式的强大功能:

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();
相关问题