web-dev-qa-db-fra.com

Comment mettre à jour un élément avec une liste en utilisant LINQ et C #

J'ai une liste d'objets et j'aimerais mettre à jour une variable membre particulière dans l'un des objets. Je comprends que LINQ est conçu pour une requête et ne vise pas à mettre à jour des listes de données immuables. Quel serait le meilleur moyen d'y parvenir? Je n'ai pas besoin d'utiliser LINQ pour la solution si ce n'est pas le plus efficace. 

La création d'une méthode d'extension Update fonctionnerait-elle? Si oui, comment pourrais-je m'y prendre?

EXAMPLE:
(from trade in CrudeBalancedList
 where trade.Date.Month == monthIndex
 select trade).Update(
 trade => trade.Buy += optionQty);
13
Addie

Bien que linq ne soit pas destiné à mettre à jour des listes de données immuables, il est très pratique pour obtenir les éléments à mettre à jour. Je pense que pour vous ce serait:

(from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).ToList().ForEach( trade => trade.Buy += optionQty);
30
Patrick Karcher

Je ne sais pas si c'est le meilleur moyen, mais vous permettra de mettre à jour un élément de la liste.

L'objet de test:

 public class SomeClass {
        public int Value { get; set; }
        public DateTime Date { get; set; }
    }

La méthode d'extension:

public static class Extension {
        public static void Update<T>(this T item, Action<T> updateAction) {
            updateAction(item);
        }
    }

Le test:

public void Test()
{
    // test data
    List<SomeClass> list = new List<SomeClass>()
    {
        new SomeClass {Value = 1, Date = DateTime.Now.AddDays(-1)},
        new SomeClass {Value = 2, Date = DateTime.Now },
        new SomeClass {Value = 3, Date = DateTime.Now.AddDays(1)}
    };
    // query and update
    (from i in list where i.Date.Day.Equals(DateTime.Now.Day) select i).First().Update(v => v.Value += 5);

    foreach (SomeClass s in list) {
        Console.WriteLine(s.Value);
    }
}
4
Fernando

Donc, vous vous attendez à obtenir un seul résultat ici. Dans ce cas, vous pouvez envisager d'utiliser la méthode SingleOrDefault:

var record =
    (from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).SingleOrDefault();

if (record != null)
    record.Buy += optionQty;

Notez que la méthode SingleOrDefault s'attend à ce que soit exactement une valeur ou une valeur nulle soit renvoyée (comme une ligne dans une table pour une clé primaire unique). Si plus d'un enregistrement est renvoyé, la méthode lève une exception.

1
Dan Tao

Pour créer une telle méthode, vous commenceriez avec son prototype:

public static class UpdateEx {
    public void Update(this IEnumerable<T> items, 
                       Expression<Action> updateAction) {
    }
}

C'est la partie facile.

La partie difficile sera de compiler le Expression<Action> dans une instruction de mise à jour SQL. Selon la syntaxe que vous souhaitez prendre en charge, la complexité d'un tel compilateur peut aller de triviale à impossible.

Pour obtenir un exemple de compilation d'expressions Linq, reportez-vous à la classe TableQuery du projet sqlite-net .

0
Frank Krueger