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

时间:2009-07-21 18:31:09

标签: c# linq collections

我有IQueryable<someClass> baseList

List<someOtherClass> someData

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

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

someOtherClass.someCode == baseList.myCode

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

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

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

5 个答案:

答案 0 :(得分:18)

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

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

这将为您提供someData中与baseList中的对应项配对的每个项目的枚举。从那里,你可以循环连接:

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

如果你真的想要设置连接而不是+=,请看一下LINQ的Union,Intersect或Except方法。

答案 1 :(得分:12)

LINQ用于查询 - 不用于更新。这意味着使用LINQ找到相应的项目会很好,但是对于应该使用迭代的修改。

不可否认,您可能需要执行一些适当的查询,以便首先将baseList转换为有效的表单 - 例如Dictionary<string, SomeClass>基于您将用于查找相应项目的属性。

答案 2 :(得分:3)

您可以将IQueryable<SomeClass>转换为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

但在使用非LINQ结构时,它可能更有效。

答案 3 :(得分:2)

如前所述,它应该是循环和LINQ的组合

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

答案 4 :(得分:0)

您不能简单地找到一个列表中的对象而不能找到另一个列表中的对象,因为它们是两种不同的类型。我假设您正在比较一个名为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);