270 Stimmen

LINQ: Ein Objekt auswählen und einige Eigenschaften ändern, ohne ein neues Objekt zu erstellen

Ich möchte einige Eigenschaften eines LINQ-Abfrageergebnisobjekts ändern, ohne ein neues Objekt zu erstellen und jede Eigenschaft manuell einzustellen. Ist dies möglich?

Beispiel:

var list = from something in someList
           select x // but change one property

1 Stimmen

Das tut mir leid! Hier ist die richtige Adresse: robvolk.com/

1 Stimmen

2 Stimmen

Dies ist zwar möglich, wie die Antworten zeigen, aber beachten Sie bitte, dass dies gegen die Natur von LINQ verstößt. LINQ-Methoden sollen keine Seiteneffekte verursachen, so dass diese Vorgehensweise nicht dem Prinzip der geringsten Überraschung entspricht. Gemäß LINQ würden Sie die Objekte abrufen und sie dann ändern.

464voto

JaredPar Punkte 699699

Ich bin mir nicht sicher, wie die Abfragesyntax lautet. Aber hier ist der erweiterte LINQ-Ausdruck Beispiel.

var query = someList.Select(x => { x.SomeProp = "foo"; return x; })

Dabei wird eine anonyme Methode gegen einen Ausdruck verwendet. Dadurch können Sie mehrere Anweisungen in einem Lambda verwenden. So können Sie die beiden Vorgänge des Festlegens der Eigenschaft und des Zurückgebens des Objekts in dieser etwas lapidaren Methode kombinieren.

0 Stimmen

Danke, Ihre Lösung funktioniert sehr gut. Wie würden Sie es mit Abfrage-Syntax schreiben?

6 Stimmen

@Rob, Nicht leicht. Die Syntax, um das zum Laufen zu bringen, ist ... bestenfalls unlesbar. var query = from it in list select ((Func<Foo>)(() => { it.x = 42; return it; }))();

51 Stimmen

Ich erhalte "Ein Lambda-Ausdruck mit einem Anweisungskörper kann nicht in einen Ausdrucksbaum konvertiert werden" Fehler. Seine nicht für LINQ to SQL, jede Beratung?

70voto

Jon Spokes Punkte 2499

Wenn Sie die Eigenschaft nur für alle Elemente aktualisieren wollen, dann

someList.All(x => { x.SomeProp = "foo"; return true; })

3 Stimmen

In EF (Entity Framework): eine Eigenschaft auf alle Objekte eines IEnumerable zu ersetzen, die akzeptierte Antwort arbeitete für mich. Funktionierender Code für mich: var myList = _db.MyObjects.Where(o => o.MyProp == "bar").AsEnumerable().Select(x => { x.SomeProp = "foo"; return x; });

37voto

Jan Zahradník Punkte 2248

Ich bevorzuge diese. Er kann mit anderen Linq-Befehlen kombiniert werden.

from item in list
let xyz = item.PropertyToChange = calcValue()
select item

3 Stimmen

Ausdrucksbäume können keine Zuweisungen enthalten

0 Stimmen

@Daniel haben Sie Ihre Hypothese vor dem Posten ausprobiert?

0 Stimmen

Ja, ich habe Ihre Lösung tatsächlich ausprobiert. Hier ist der neueste Vorschlag zum Hinzufügen dieser Funktionalität zu c#: github.com/dotnet/csharplang/diskussionen/4727

33voto

Joshua Belden Punkte 9673

Es sollte keine LINQ-Magie sein, die Sie davon abhält, dies zu tun. Verwenden Sie keine Projektion aber, die einen anonymen Typ zurückgeben wird.

User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"

Dadurch wird auch das reale Objekt verändert:

foreach (User u in UserCollection.Where(u => u.Id > 10)
{
    u.Property = SomeValue;
}

0 Stimmen

Ich mag das, meine Frage ist im ersten Beispiel, was, wenn einige u > 10 ist nicht in der Liste gefunden? Ich habe eine Nullprüfung hinzugefügt und es scheint zu funktionieren. Auch LHS ich genannt u zu v. +1 obwohl. Sehr prägnant.

14voto

Pierre Punkte 7297

Wenn Sie Elemente mit einer Where Klausel, die Verwendung einer .Where(...) wird Ihre Ergebnisse abschneiden, wenn Sie dies tun:

list = list.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();

Sie können bestimmte Elemente in der Liste wie folgt aktualisieren:

list = list.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();

Senden Sie den Artikel immer zurück, auch wenn Sie keine Änderungen vornehmen. Auf diese Weise bleibt er in der Liste erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X