如何在 LINQ 中更改值而不进行新投影?

发布于 2024-10-23 21:01:52 字数 771 浏览 1 评论 0原文

我有以下 LINQ 查询:

var source = from node in MyNods
             select new
             {
                 Id = node.Id,
                 Name = node.Name,
                 ParentId = node.ParentId, // Nullable
             };

在上面的查询中,ParentId 可为空。现在我需要一个与第一个结果匹配的新结果,但有一些小变化,如果 ParentId 为 null,我希望它为 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 都可为空。

I have the following LINQ query:

var source = from node in MyNods
             select new
             {
                 Id = node.Id,
                 Name = node.Name,
                 ParentId = node.ParentId, // Nullable
             };

In the query above, the ParentId is nullable. Now I need a new result which is match the first one but with small change that if ParentId is null I want it to be 0.

I wrote this:

var source2 =  from s in source
               select new
               {
                    Id = s.Id,
                    Name = s.Name,
                    ParentId = s.ParentId ?? 0, // Just change null values to 0
               };

Can I implement that with a simpler way (I mean without the new projection) ?

Edit: The new projection is the same of the first one and both ParentId are nullable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若水般的淡然安静女子 2024-10-30 21:01:52

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

编辑:
根据您的编辑,现在看来您不需要不同的类型来表示投影数据,因为“合并”属性仍然可以为空。如果您不想改变现有集合并且不喜欢当前的查询,那么最好的选择仍然是在源类型中编写转换方法。

LINQ isn't ideal for executing side-effects on an existing collection. If that's what you want to do, you'd be better off doing:

foreach(var node in MyNods)
{
   if(!node.ParentId.HasValue) 
      node.ParentId = 0;
}

If that's not the case, you're going to have to project. Your existing query is perfectly fine; the only way I can think of shortening it is:

var source2 =  from s in source
               select new
               {
                    s.Id, s.Name,
                    ParentId = s.ParentId ?? 0
               };

EDIT:
It appears you're trying to create an instance of a different type (i.e. with virtually the same properties as the source but with one specific property being non-nullable), so you can't escape creating instances of the new type and copying properties over. You might want to consider writing a 'real' (non-anonymous) type that represents what you want and get the source-type to provide a conversion-method. Then you can do:

var source2 = source.Select(s => s.ToNonNullableParentVersion());

EDIT:
From your edit, it now appears that you don't need a different type to represent the projected data since the 'coalesced' property is still meant to be nullable. If you don't want to mutate the existing collection and you don't like your current query, your best bet would still be to write a conversion method in the source-type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文