2009-07-21 21 views
16

Ich habe IQueryable<someClass> baseListLinq, um eine Sammlung mit Werten aus einer anderen Sammlung zu aktualisieren?

und List<someOtherClass> some

Was will ich Update tun, ist in einigen Elementen in baseList Attributen.

Für jedes Element in someData möchte ich das entsprechende Element in der Basisliste finden und eine Eigenschaft des Elements aktualisieren.

someOtherClass.someCode == baseList.myCode

kann ich irgendeine Art mit Linq von verbinden und setzen baseList.someData + = someOtherClass.DataIWantToConcantenate.

Ich könnte das wahrscheinlich durch Iteration tun, aber gibt es eine schicke Linq Weise kann ich das in nur ein paar Zeilen Code tun?

Vielen Dank für alle Tipps, ~ ck in San Diego

Antwort

19

Um Elemente in den beiden Listen paaren Sie eine LINQ beitreten können:

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

Diese Sie in someData eine Aufzählung der einzelnen Elemente geben gepaart mit seinem Gegenstück in baseList. Von dort können Sie in einer Schleife verketten:

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

Wenn Sie wirklich eher Satz Verkettung gemeint als +=, werfen Sie einen Blick auf LINQ der Union, Intersect oder Außer-Methoden.

+0

Das hat super für mich funktioniert. Vielen Dank! – Hcabnettek

+0

Vielen Dank !! – PramodChoudhari

12

LINQ ist für Abfrage - nicht für die Aktualisierung. Das bedeutet, dass es in Ordnung ist, LINQ zu verwenden, um das entsprechende Element zu finden, aber für die Änderung sollte Iteration verwenden.

Zugegebenermaßen möchten Sie möglicherweise eine entsprechende Abfrage durchführen, um baseList zuerst in eine effiziente Form zu bringen - z. a Dictionary<string, SomeClass> basierend auf der Eigenschaft, die Sie verwenden werden, um den entsprechenden Artikel zu finden.

3

Sie können die IQueryable<SomeClass> in eine List<SomeClass> konvertieren, verwenden Sie die ForEach Methode über sie in einer Schleife und die Elemente aktualisieren, dann konvertieren zurück zu 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 

Aber es kann während dieser Verwendung nicht effizienter LINQ-Konstrukte

+0

es funktionieren würde eine Kreuzung zwischen diesem Ansatz zu tun, und dem akzeptierten Ansatz, z.B. (von d in someData Join b in BaseList.AsEnumerable() auf D.SomeCode entspricht b.myCode wähle new {b, d}). ToList.ForEach (a => { a.b.SomeData + = a.d.DataIWantToConcatenate; }); – stevenrcfox

0

Sie können nicht einfach Objekte in der einen, sondern in der anderen Liste finden, da es sich um zwei verschiedene Typen handelt. Ich gehe davon aus, dass Sie eine Eigenschaft namens OtherProperty vergleichen, die den beiden verschiedenen Klassen gemeinsam ist und denselben Typ hat. In diesem Fall fragt mit nichts als 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); 
2

Wie bereits erwähnt, soll es eine Kombination von Schleife und LINQ seines

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