Comment mettre à jour une valeur dans une liste à l’aide de LINQ

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

class Student { private ssortingng name; private int marks; public ssortingng Name { get; set;} public int Marks { get; set; } public Student(ssortingng name, int marks) { Name = name; Marks = marks; } } List myList = new List(); 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?

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.

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 myList le résultat à myList la requête ci-dessus modifiera la valeur de la liste d’origine. N’oubliez pas que c’est un effet secondaire et que ce n’est pas la bonne façon 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.

Essayer:

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

que diriez-vous de bon vieux for boucle

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

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; 

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(); 

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

Exemple

  static void Main(ssortingng[] args) { List testList = new List() { 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 Ssortingng Text { get; set; } } 

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

Première valeur textuelle: Text2

Valeur texte modifiée: Hello You !!

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

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