it-swarm.com.de

LINQ: Wählen Sie ein Objekt aus und ändern Sie einige Eigenschaften, ohne ein neues Objekt zu erstellen

Wenn ich mit LINQ eine Abfrage ausführen und das Objekt aus der Abfrage zurückgeben wollte, aber nur einige Eigenschaften in diesem Objekt ändern würde, wie kann ich dies tun, ohne ein neues Objekt zu erstellen und jede Eigenschaft manuell festzulegen? Ist das möglich?

Beispiel:

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

Ich bin nicht sicher, was die Abfragesyntax ist. Hier ist jedoch das erweiterte Beispiel für den LINQ-Ausdruck.

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

Verwenden Sie dazu eine anonyme Methode vs und einen Ausdruck. Dadurch können Sie mehrere Anweisungen in einem Lambda verwenden. Sie können also die beiden Operationen zum Festlegen der Eigenschaft und zum Zurückgeben des Objekts in dieser etwas knappen Methode kombinieren.

326
JaredPar

Wenn Sie nur die Eigenschaft für alle Elemente aktualisieren möchten 

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

Ich bevorzuge das hier. Es kann mit anderen linq-Befehlen kombiniert werden.

from item in list
let xyz = item.PropertyToChange = calcValue()
select item
27
Jan Zahradník

Es sollte keine LINQ-Magie geben, die Sie davon abhält. Verwenden Sie keine Projektion, obwohl ein anonymer Typ zurückgegeben wird.

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

Das wird das reale Objekt verändern, sowie:

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

Mit den Standardabfrageoperatoren ist dies nicht möglich - es ist Language Integrated Query, nicht Language Integrated Update. Sie können Ihr Update jedoch in Erweiterungsmethoden ausblenden.

public static class UpdateExtension
{
    public static IEnumerable<Car> ChangeColorTo(
       this IEnumerable<Car> cars, Color color)
    {
       foreach (Car car in cars)
       {
          car.Color = color;
          yield return car;
       }
    }
}

Jetzt können Sie es wie folgt verwenden.

cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);
9

Wenn Sie Elemente mit einer Where-Klausel aktualisieren möchten, werden die Ergebnisse mit einem .Where (...) abgeschnitten.

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

Sie können Aktualisierungen für bestimmte Elemente in der Liste wie folgt durchführen:

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

Artikel immer zurücksenden, auch wenn Sie keine Änderungen vornehmen. Auf diese Weise wird es in der Liste gehalten.

2
Pierre

Wir stoßen oft darauf, dass wir den Indexwert und die ersten und letzten Indikatoren in eine Liste aufnehmen möchten, ohne ein neues Objekt zu erstellen. Auf diese Weise können Sie die Position des Elements in Ihrer Liste, die Aufzählung usw. ermitteln, ohne die vorhandene Klasse ändern zu müssen und dann zu wissen, ob Sie sich beim ersten oder letzten Element der Liste befinden.

foreach (Item item in this.Items
    .Select((x, i) => {
    x.ListIndex = i;
    x.IsFirst = i == 0;
    x.IsLast = i == this.Items.Count-1;
    return x;
}))

Sie können jede Klasse einfach erweitern, indem Sie Folgendes verwenden:

public abstract class IteratorExtender {
    public int ListIndex { get; set; }
    public bool IsFirst { get; set; } 
    public bool IsLast { get; set; } 
}

public class Item : IteratorExtender {}
0
Informitics
var item = (from something in someList
       select x).firstordefault();

Ich würde item bekommen, und dann könnten Sie item.prop1=5; tun, um die spezifische Eigenschaft zu ändern.

Oder möchten Sie eine Liste der Elemente aus der Datenbank abrufen und die Eigenschaft prop1 für jedes Element in der zurückgegebenen Liste in einen angegebenen Wert ändern? Wenn dies möglich ist, tun Sie dies (ich mache es in VB weil ich es besser kenne):

dim list = from something in someList select x
for each item in list
    item.prop1=5
next

(list enthält alle Elemente, die mit Ihren Änderungen zurückgegeben werden.)

0
Solmead

Da ich hier nicht die Antwort gefunden habe, die ich für die beste Lösung halte, hier mein Weg:

Die Verwendung von "Auswählen" zum Ändern von Daten ist nur mit einem Trick möglich. Jedenfalls ist "Select" dafür nicht gemacht. Bei der Verwendung von "ToList" wird lediglich die Änderung ausgeführt, da Linq nicht ausgeführt wird, bevor die Daten benötigt werden. Im folgenden Code sehen Sie:

    class Person
    {
        public int Age;
    }

    class Program
    {
        private static void Main(string[] args)
        {
            var persons = new List<Person>(new[] {new Person {Age = 20}, new Person {Age = 22}});
            PrintPersons(persons);

            //this doesn't work:
            persons.Select(p =>
            {
                p.Age++;
                return p;
            });
            PrintPersons(persons);

            //with "ToList" it works
            persons.Select(p =>
            {
                p.Age++;
                return p;
            }).ToList();
            PrintPersons(persons);

            //This is the best solution
            persons.ForEach(p =>
            {
                p.Age++;
            });
            PrintPersons(persons);
            Console.ReadLine();
        }

        private static void PrintPersons(List<Person> persons)
        {
            Console.WriteLine("================");
            foreach (var person in persons)
            {
                Console.WriteLine("Age: {0}", person.Age);
            ;
            }
        }
    }

Vor "foreach" können Sie auch eine linq-Auswahl treffen ... 

0
Stefan R.