我们很难通过在获取数据后声明循环来找出解决此问题的最佳方法。
例如,取这段代码:( 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
}
}
}
是否有更清洁/更好的方法将其保留在原始选择循环中。
由于
答案 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();