web-dev-qa-db-fra.com

Comment mettre à jour une valeur dans une liste en utilisant LINQ

J'ai une liste que je veux mettre à jour avec LINQ.

class Student
{
    private string name;
    private int marks;
    public string Name { get; set;}
    public int Marks { get; set; }
    public Student(string name, int marks)
    {
        Name = name;
        Marks = marks;
    }
}

List<Student> myList = new List<Student>();
myList.Add(new Student("John", 10));
myList.Add(new Student("Tom", 20));

Maintenant, je veux mettre à jour la liste en utilisant LINQ de telle sorte que seules les marques de John soient mises à jour. J'utilise la syntaxe suivante:

myList.Where(w => w.Name == "Tom").Select(w=> { w.Marks = 35; return w});

Mais cela ne met pas à jour les données dans myList. Quelqu'un peut-il me dire où je me trompe?.

2
user3625024

LINQ sert à interroger et non à mettre à jour les données. Utilisez LINQ pour obtenir les éléments que vous souhaitez modifier, puis modifiez-les dans une boucle foreach:

foreach ( var tom in myList.Where(w => w.Name == "Tom")) {
    tom.Marks = 35;
}

Démo.

22
dasblinkenlight

Comme d'autres l'ont souligné, LINQ sert à interroger des données, pas à effectuer des mises à jour.

Vous devriez itérer votre liste et modifier vos valeurs comme:

foreach (var student in myList)
{
    if (student.Name == "Tom")
    {
        student.Marks = 35;
    }
}

Ou

foreach (var student in myList.Where(r => r.Name == "Tom"))
{
    student.Marks = 35;
}

Quoi que vous pensiez mieux traduit l'intention utilisée.


mais voici une chose intéressante:

Si vous avez une déclaration comme:

myList.Where(w => w.Name == "Tom").Select(w => w.Marks = 35).ToList();

Sans affecter le résultat à myList, la requête ci-dessus modifiera la valeur dans la liste d'origine. Souvenez-vous que c’est un effet secondaire et que ce n’est pas le approprié moyen de mettre à jour . Cette modification peut être expliquée par le paramètre de référence transmis à une méthode et y étant modifié. Mais surtout, cela devrait toujours être évité . C'est une mauvaise pratique et pourrait conduire à un code vraiment déroutant. Utilisez LINQ pour interroger uniquement.

5
Habib

Essayer:

myList .Where(w=> w.Name  == "dTomi").ToList().ForEach(i => i.Marks  = 35);
2
SHIBIN

Les objets sont stockés par référence dans la liste afin que vous puissiez récupérer un objet via linq puis le modifier, il reflétera les modifications apportées à la liste.

Exemple

    static void Main(string[] args)
        {
            List<Entity> testList = new List<Entity>()
            {
                new Entity() {Id = 1, Text = "Text"},
                new Entity() {Id = 2, Text = "Text2"}
            };

            Console.WriteLine($"First text value:{testList[1].Text}");

            Entity entityToEdit = testList.FirstOrDefault(e => e.Id == 2);
            if (entityToEdit != null)
                entityToEdit.Text = "Hello You!!";

            Console.WriteLine($"Edited text value:{testList[1].Text}");

            Console.ReadLine();
        }

 internal class Entity
    {
        public int Id { get; set; }
        public String Text { get; set; }
    }

En testant l'application, vous obtiendrez le résultat suivant:

Première valeur textuelle: Text2

Valeur du texte édité: Hello You !!

0
Final Nemael

que diriez-vous de la bonne vieille boucle for

for(int i = 0; i < myList.Count; i++)
if (myList[i].Name  == "Tom")
{
    myList[i].Marks = 35;
    break;
}
0
ASh

bien @dasblinkenlight code devrait fonctionner, mais vous pouvez également essayer quelque chose comme ça

 var query = from x in list
             where x.Name = yourcondition
             select new { x };
foreach(var item in query)
   item.x.FieldToUpdate = SetValue;
0
user2726374

C'est un peu maladroit, mais cela fonctionne et ne dépend pas de la transmission d'une référence. Il crée une nouvelle liste basée sur l'ancien.

var myList=myList.Select(l=>new Student { 
   l.Name,
   Marks=l.Name=="Tom"?35:l.Marks}).ToList();

Ou plus bête:

var myList=myList.Where(l=>l.Name!="Tom").Union(
  myList.Where(l=>l.Name=="Tom").Select(l=>new Student { 
   l.Name,
   Marks=35})).ToList();
0
Robert McKee

Ci-dessus peut être atteint en attribuant simplement la valeur à la collection

myList = myList
        .Where(w => w.Name == "Tom")
        .Select(w=> { w.Marks = 35; return w})
        .ToList();
0
Sathish