LINQ: выберите объект и измените некоторые свойства, не создавая новый объект

Используя LINQ, если бы я хотел выполнить некоторый запрос и вернуть объект из запроса, но изменил только некоторые свойства этого объекта, как бы это сделать без создания нового объекта и вручную установить каждое свойство? Возможно ли это?

Пример:

var list = from something in someList
           select x // but change one property

Ответ 1

Я не уверен, что такое синтаксис запроса. Но вот расширенный пример выражения LINQ.

var query = someList.Select(x => { x.SomeProp = "foo"; return x; })

Это означает использование анонимного метода vs и expression. Это позволяет использовать несколько операторов в одной лямбда. Таким образом, вы можете объединить две операции по настройке свойства и возврату объекта в этот несколько сжатый метод.

Ответ 2

Если вы просто хотите обновить свойство для всех элементов, то

someList.All(x => { x.SomeProp = "foo"; return true; })

Ответ 3

Я предпочитаю этот. Он может быть объединен с другими командами linq.

from item in list
let xyz = item.PropertyToChange = calcValue()
select item

Ответ 4

Не должно быть никаких волшебств 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;
}

Ответ 5

Это невозможно для стандартных операторов запросов - это Language Integrated Query, а не Language Integrated Update. Но вы можете скрыть свое обновление в методах расширения.

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

Ответ 6

var item = (from something in someList
       select x).firstordefault();

Получил бы элемент, и тогда вы могли бы сделать item.prop1 = 5; для изменения конкретного свойства.

Или вы хотите получить список элементов из db и изменить его свойство prop1 для каждого элемента в этом возвращенном списке до указанного значения? если так вы могли бы это сделать (я делаю это в VB, потому что я знаю это лучше):

dim list = from something in someList select x
for each item in list
    item.prop1=5
next

(список будет содержать все элементы, возвращенные с вашими изменениями)

Ответ 7

Так как я не нашел ответа здесь, который я считаю лучшим решением, здесь мой способ:

Использование "Выбрать" для изменения данных возможно, но просто с трюком. Во всяком случае, "Select" для этого не делается. Он просто выполняет модификацию при использовании с "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...

Ответ 8

User u = UserCollection.Single(u => u.Id == 1);
u.FirstName = "Bob"