2009-07-21 11 views
16

Mam IQueryable<someClass> baseListLinq, aby zaktualizować kolekcję wartościami z innej kolekcji?

i List<someOtherClass> someData

Co chcę zrobić jest zmiana atrybutów w niektórych elementów w baseList.

Dla każdej pozycji w niektórych danych, chcę znaleźć odpowiedni element na liście bazowej i zaktualizować właściwość elementu.

someOtherClass.someCode == baseList.myCode

mogę zrobić jakiś rodzaj przyłączenia Linq i ustawić baseList.someData + = someOtherClass.DataIWantToConcantenate.

Prawdopodobnie mógłbym to zrobić przez iterację, ale czy istnieje styl Linq, który mogę zrobić w zaledwie kilku liniach kodu?

Dzięki za wszelkie wskazówki, ~ ck w San Diego

Odpowiedz

19

Aby powiązać elementy w dwóch wykazach można użyć LINQ przyłączyć:

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

To daje wyliczenie każdego elementu w someData sparowany z jego odpowiednikiem w baseList. Stamtąd można złączyć w pętli:

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

Jeśli naprawdę oznaczało zestaw konkatenacji zamiast +=, spójrz na LINQ w Unii, Przecięcie lub Wyłączając metod.

+0

To zadziałało dla mnie świetnie. Dziękuję Ci! – Hcabnettek

+0

Wielkie dzięki! – PramodChoudhari

12

LINQ jest zapytań - nie do aktualizacji. Oznacza to, że dobrze będzie użyć LINQ do znalezienia odpowiedniego elementu, ale w przypadku modyfikacji musisz używaćiteracji.

Prawdą jest, że warto wykonać odpowiednie zapytanie, aby najpierw uzyskać baseList w sprawną formę - np. a Dictionary<string, SomeClass> w oparciu o właściwość używaną do znalezienia odpowiedniego elementu.

3

można przekonwertować IQueryable<SomeClass> w List<SomeClass>, użyj metody do pętli nad nim ForEach i aktualizować elementy, a następnie przekształcić z powrotem do 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 

Ale może to być bardziej efektywne podczas tego za pomocą nie- Konstrukty LINQ.

+0

będzie działać zrobić krzyżówki tego podejścia i przyjętej metody, np (z d w someData dołączyć b w baseList.AsEnumerable() na d.someCode równa się b.myCode wybierz nowy {b, d}). ToList.ForEach (a => { a.b.SomeData + = a.D.DataIWantToConcatenate; }); – stevenrcfox

0

Nie można po prostu znaleźć obiektów znajdujących się na jednej liście, ale nie drugiej, ponieważ są to dwa różne typy. Zakładam, że porównujesz właściwość o nazwie OtherProperty, która jest wspólna dla dwóch różnych klas i ma ten sam typ właściwości. W takim przypadku, przy użyciu jedynie Linq pyta:

// 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); 
2

Jak wspomniano powyżej, powinno to być połączenie pętli i LINQ

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