Linq обновить коллекцию значениями из другой коллекции? - PullRequest
17 голосов
/ 21 июля 2009

У меня есть IQueryable<someClass> baseList

и List<someOtherClass> someData

Я хочу обновить атрибуты некоторых элементов в baseList.

Для каждого элемента в someData я хочу найти соответствующий элемент в базовом списке и обновить свойство элемента.

someOtherClass.someCode == baseList.myCode

можно ли выполнить какое-либо соединение с помощью Linq и установить baseList.someData + = someOtherClass.DataIWantToConcantenate.

Возможно, я мог бы сделать это путем итерации, но есть ли причудливый способ Linq, которым я могу сделать это всего за пару строк кода?

Спасибо за любые советы, ~ ck в Сан-Диего

Ответы [ 5 ]

18 голосов
/ 21 июля 2009

Для объединения элементов в двух списках вы можете использовать соединение 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.

12 голосов
/ 21 июля 2009

LINQ для запросов - не для обновления. Это означает, что будет нормально использовать LINQ для поиска соответствующего элемента, но для модификации вы должны использовать итерацию.

Возможно, вы захотите выполнить какой-нибудь соответствующий запрос, чтобы сначала получить baseList в эффективную форму, например, например. Dictionary<string, SomeClass> в зависимости от свойства, которое вы будете использовать для поиска соответствующего элемента.

4 голосов
/ 21 июля 2009

Вы можете преобразовать 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 конструкций.

2 голосов
/ 13 января 2011

Как упоминалось ранее, это должна быть комбинация цикла и LINQ

foreach (var someDataItem in someData)
{
    someDataItem.PropertyToUpdate = (baseList.FirstOrDefault(baseListItem => baseListItem .key == someDataItem.key) ?? new SomeClass(){OtherProperty = "OptionalDefaultValue"}).OtherProperty;
}
0 голосов
/ 21 июля 2009

Вы не можете просто найти объекты, которые находятся в одном списке, но не в другом, потому что это два разных типа. Я предполагаю, что вы сравниваете свойство с именем 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...