c# - query - LINQ: selecciona un objeto y cambia algunas propiedades sin crear un nuevo objeto
linq c# tutorial español (8)
Como no encontré aquí la respuesta que considero la mejor solución, aquí a mi manera:
Usar "Seleccionar" para modificar datos es posible, pero solo con un truco. De todos modos, "Seleccionar" no está hecho para eso. Simplemente ejecuta la modificación cuando se usa con "ToList", porque Linq no se ejecuta antes de que se necesiten los datos. De todos modos, la mejor solución es usar "foreach". En el siguiente código, puedes ver:
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);
;
}
}
}
Antes de "foreach", también puedes hacer una selección de linq ...
Usando LINQ, si quería realizar una consulta y devolver el objeto de la consulta, pero cambiar solo algunas de las propiedades en ese objeto, ¿cómo haría esto sin crear un nuevo objeto y configurar manualmente cada propiedad? es posible?
Ejemplo:
var list = from something in someList
select x // but change one property
No debería haber ninguna magia LINQ que te impida hacer esto. Sin embargo, no utilice una proyección que devuelva un tipo anónimo.
User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"
Eso modificará el objeto real, así como también:
foreach (User u in UserCollection.Where(u => u.Id > 10)
{
u.Property = SomeValue;
}
No es posible con los operadores de consulta estándar: es Language Integrated Query, no Language Integrated Update. Pero podría ocultar su actualización en métodos de extensión.
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;
}
}
}
Ahora puedes usarlo de la siguiente manera.
cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);
No estoy seguro de cuál es la sintaxis de la consulta. Pero aquí está el ejemplo expandido de expresión LINQ.
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
Lo que hace es usar un método anónimo vs y expresión. Esto le permite usar varias instrucciones en una lambda. De modo que puede combinar las dos operaciones de configuración de la propiedad y devolver el objeto a este método un tanto breve.
Prefiero éste. Se puede combinar con otros comandos linq.
from item in list
let xyz = item.PropertyToChange = calcValue()
select item
Si solo desea actualizar la propiedad en todos los elementos, entonces
someList.All(x => { x.SomeProp = "foo"; return true; })
User u = UserCollection.Single(u => u.Id == 1);
u.FirstName = "Bob"
var item = (from something in someList
select x).firstordefault();
Obtendría el artículo, y luego podría hacer item.prop1 = 5; para cambiar la propiedad específica.
¿O desea obtener una lista de elementos de la base de datos y hacer que cambie la propiedad prop1 de cada elemento en esa lista devuelta a un valor específico? de ser así, podrías hacer esto (lo estoy haciendo en VB porque lo sé mejor):
dim list = from something in someList select x
for each item in list
item.prop1=5
next
(la lista contendrá todos los artículos devueltos con sus cambios)