Я хочу изменить некоторые свойства объекта результата запроса LINQ без создания нового объекта и установки каждого свойства вручную. Это возможно?
Пример:
var list = from something in someList
select x // but change one property
Я хочу изменить некоторые свойства объекта результата запроса LINQ без создания нового объекта и установки каждого свойства вручную. Это возможно?
Пример:
var list = from something in someList
select x // but change one property
Ответы:
Я не уверен, что синтаксис запроса. Но вот расширенный пример выражения LINQ.
var query = someList.Select(x => { x.SomeProp = "foo"; return x; })
Что это делает, это использовать анонимный метод против и выражение. Это позволяет использовать несколько операторов в одной лямбде. Таким образом, вы можете объединить две операции установки свойства и возврата объекта в этот несколько лаконичный метод.
ToList()
до этого, кажется, делает свое дело. Не уверен, почему вы это получаете, хотя. Если это Entity Framework, он также не работает с этим.
Если вы просто хотите обновить свойство для всех элементов, то
someList.All(x => { x.SomeProp = "foo"; return true; })
Я предпочитаю этот. Это может быть объединено с другими командами linq.
from item in list
let xyz = item.PropertyToChange = calcValue()
select item
Там не должно быть никакой магии LINQ, удерживающей вас от этого. Не используйте проекцию, хотя это вернет анонимный тип.
User u = UserCollection.FirstOrDefault(u => u.Id == 1);
u.FirstName = "Bob"
Это изменит реальный объект, а также:
foreach (User u in UserCollection.Where(u => u.Id > 10)
{
u.Property = SomeValue;
}
Это невозможно со стандартными операторами запросов - это встроенный запрос языка, а не встроенное обновление языка. Но вы можете скрыть свое обновление в методах расширения.
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;
}
}
}
Теперь вы можете использовать его следующим образом.
cars.Where(car => car.Color == Color.Blue).ChangeColorTo(Color.Red);
UPDATE
, DELETE
и INSERT
. Поэтому я бы не стал утверждать, что семантика препятствует этой функции.
Если вы хотите обновить элементы с помощью Where
предложения, использование .Where (...) будет обрезать ваши результаты, если вы сделаете:
mylist = mylist.Where(n => n.Id == ID).Select(n => { n.Property = ""; return n; }).ToList();
Вы можете сделать обновления для определенного элемента (ов) в списке следующим образом:
mylist = mylist.Select(n => { if (n.Id == ID) { n.Property = ""; } return n; }).ToList();
Всегда возвращайте товар, даже если вы не вносите никаких изменений. Таким образом, он будет сохранен в списке.
Мы часто сталкиваемся с этим, когда хотим включить значение индекса, а также первый и последний показатели в список, не создавая новый объект. Это позволяет вам узнать положение элемента в вашем списке, перечислении и т. Д. Без необходимости изменять существующий класс, а затем узнавать, находитесь ли вы у первого элемента в списке или у последнего.
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;
}))
Вы можете просто расширить любой класс, используя:
public abstract class IteratorExtender {
public int ListIndex { get; set; }
public bool IsFirst { get; set; }
public bool IsLast { get; set; }
}
public class Item : IteratorExtender {}
Так как я не нашел здесь ответа, который считаю лучшим решением, вот мой путь:
Использование «Выбрать» для изменения данных возможно, но только с хитростью. В любом случае, «Выбор» не предназначен для этого. Он просто выполняет модификацию при использовании с «ToList», потому что Linq не выполняется до того, как потребуются данные. В любом случае, лучшее решение - использовать foreach. В следующем коде вы можете увидеть:
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);
;
}
}
}
Перед "foreach", вы также можете сделать выбор linq ...
var item = (from something in someList
select x).firstordefault();
Получите item
, и тогда вы могли бы сделатьitem.prop1=5;
чтобы изменить конкретное свойство.
Или вы хотите получить список элементов из базы данных и изменить его свойство prop1
каждого элемента в этом возвращенном списке на указанное значение? Если это так, вы могли бы сделать это (я делаю это в VB, потому что я знаю это лучше):
dim list = from something in someList select x
for each item in list
item.prop1=5
next
( list
будет содержать все элементы, возвращенные с вашими изменениями)
for each
цикл.
В 2020 году я использую MoreLinq
Pipe
метод. https://morelinq.github.io/2.3/ref/api/html/M_MoreLinq_MoreEnumerable_Pipe__1.htm
User u = UserCollection.Single(u => u.Id == 1);
u.FirstName = "Bob"