我有以下LINQ查询:
var source = from node in MyNods
select new
{
Id = node.Id,
Name = node.Name,
ParentId = node.ParentId, // Nullable
};
在上面的查询中,ParentId
可以为空。现在我需要一个与第一个匹配的新结果,但如果ParentId
为空,则需要进行少量更改,我希望它为0
。
我写了这个:
var source2 = from s in source
select new
{
Id = s.Id,
Name = s.Name,
ParentId = s.ParentId ?? 0, // Just change null values to 0
};
我可以用更简单的方式实现它(我的意思是没有新的投影)?
修改:新投影与第一个投影相同,ParentId
都可以为空。
答案 0 :(得分:4)
LINQ不适合在现有集合上执行副作用。如果这就是你想做的事情,你最好做的事情是:
foreach(var node in MyNods)
{
if(!node.ParentId.HasValue)
node.ParentId = 0;
}
如果情况并非如此,那么你将不得不进行投射。您现有的查询完全没问题;我能想到缩短它的唯一方法是:
var source2 = from s in source
select new
{
s.Id, s.Name,
ParentId = s.ParentId ?? 0
};
编辑: 您似乎正在尝试创建不同类型的实例(即具有与源几乎相同的属性但具有一个特定属性不可为空),因此您无法转义创建实例新的类型和复制属性。您可能需要考虑编写一个表示所需内容的“真实”(非匿名)类型,并获取源类型以提供转换方法。然后你可以这样做:
var source2 = source.Select(s => s.ToNonNullableParentVersion());
编辑: 从您的编辑开始,现在看来您不需要不同的类型来表示投影数据,因为'coalesced'属性仍然可以为空。如果您不想改变现有的集合并且不喜欢当前的查询,那么最好的选择仍然是在源类型中编写转换方法。