C# Linq 使用另一个集合中的值更新集合?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1160903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:40:21  来源:igfitidea点击:

Linq to update a collection with values from another collection?

c#linqcollections

提问by Hcabnettek

I have IQueryable<someClass>baseList

我有IQueryable<someClass>baseList

and List<someOtherClass>someData

List<someOtherClass>一些数据

What I want to do is update attributes in some items in baseList.

我想要做的是更新 baseList 中某些项目的属性。

For every item in someData, I want to find the corresponding item in baselist and update a property of the item.

对于 someData 中的每个项目,我想在 baselist 中找到相应的项目并更新该项目的属性。

someOtherClass.someCode == baseList.myCode

someOtherClass.someCode == baseList.myCode

can I do some type of join with Linq and set baseList.someData += someOtherClass.DataIWantToConcantenate.

我可以与 Linq 进行某种类型的连接并设置 baseList.someData += someOtherClass.DataIWantToConcantenate。

I could probably do this by iteration, but is there a fancy Linq way I can do this in just a couple lines of code?

我可能可以通过迭代来做到这一点,但是有没有一种花哨的 Linq 方式我可以只用几行代码来做到这一点?

Thanks for any tips, ~ck in San Diego

感谢您的任何提示,圣地亚哥的〜ck

采纳答案by dahlbyk

To pair elements in the two lists you can use a LINQ join:

要配对两个列表中的元素,您可以使用 LINQ 连接:

var pairs = from d in someData
            join b in baseList.AsEnumerable()
                on d.someCode equals b.myCode
            select new { b, d };

This will give you an enumeration of each item in someDatapaired with its counterpart in baseList. From there, you can concatenate in a loop:

这将为您提供someDatabaseList. 从那里,您可以在循环中连接:

foreach(var pair in pairs)
    pair.b.SomeData += pair.d.DataIWantToConcantenate;

If you really meant set concatenation rather than +=, take a look at LINQ's Union, Intersect or Except methods.

如果您的意思是 set concatenation 而不是+=,请查看 LINQ 的 Union、Intersect 或 except 方法。

回答by Jon Skeet

LINQ is for querying- not for updating. That means it'll be fine to use LINQ to find the corresponding item, but for the modification you shouldbe using iteration.

LINQ 用于查询- 不用于更新。这意味着可以使用 LINQ 来查找相应的项目,但是对于修改,您应该使用迭代。

Admittedly you might want to perform some appropriate query to get baseListinto an efficient form first - e.g. a Dictionary<string, SomeClass>based on the property you'll be using to find the corresponding item.

诚然,您可能希望先执行一些适当的查询以baseList进入有效的表单 - 例如,Dictionary<string, SomeClass>基于您将用于查找相应项目的属性。

回答by Fredrik M?rk

You can convert the IQueryable<SomeClass>into a List<SomeClass>, use the ForEachmethod to loop over it and update the elements, then convert back to IQueryable:

您可以将 转换IQueryable<SomeClass>为 a List<SomeClass>,使用该ForEach方法循环并更新元素,然后转换回IQueryable

List<SomeClass> convertedList = baseList.ToList();
convertedList.ForEach(sc =>
{
    SomeOtherClass oc = someData.First(obj => obj.SomeCode == sc.MyCode);
    if (oc != null)
    {
        sc.SomeData += oc.DataIWantToConcatenate;
    }
});

baseList = convertedList.AsQueryable(); // back to IQueryable

But it may be more efficient during this using non-LINQ constructs.

但是在此期间使用非 LINQ 构造可能更有效。

回答by IRBMe

You can't simply find objects that are in one list but not the other, because they are two different types. I'll assume you're comparing a property called OtherProperty that is common to the two different classes, and shares the same type. In that case, using nothing but Linq queries:

您不能简单地找到在一个列表中而不在另一个列表中的对象,因为它们是两种不同的类型。我假设您正在比较两个不同类共有的名为 OtherProperty 的属性,并且共享相同的类型。在这种情况下,只使用 Linq 查询:

// update those items that match by creating a new item with an
// updated property
var updated =
    from d in data
    join b in baseList on d.OtherProperty equals b.OtherProperty
    select new MyType()
    {
        PropertyToUpdate = d.PropertyToUpdate,
        OtherProperty = d.OtherProperty
    };

// and now add to that all the items in baseList that weren't found in data
var result =
    (from b in baseList
     where !updated.Select(x => x.OtherProperty).Contains(b.OtherProperty)
     select b).Concat(updated);

回答by Valera

As mentioned before, it should be a combination of loop and LINQ

前面说过,应该是loop和LINQ的结合

foreach (var someDataItem in someData)
{
    someDataItem.PropertyToUpdate = (baseList.FirstOrDefault(baseListItem => baseListItem .key == someDataItem.key) ?? new SomeClass(){OtherProperty = "OptionalDefaultValue"}).OtherProperty;
}