我有以下 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 都可以为空。

最佳答案

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' 属性仍然可以为空。如果您不想改变现有集合并且不喜欢当前查询,那么最好的办法仍然是在源类型中编写转换方法。

关于c# - 如何在 LINQ 中没有新投影的情况下更改值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5338747/

10-13 05:53