Подтвердить что ты не робот

Как обновить элемент с помощью List с помощью LINQ и С#

У меня есть список объектов, и я хотел бы обновить определенную переменную-член в одном из объектов. Я понимаю, что LINQ предназначен для запроса и не предназначен для обновления списков неизменяемых данных. Какой был бы лучший способ сделать это? Мне не нужно использовать LINQ для решения, если оно не является наиболее эффективным.

Будет ли создание метода расширения Update работать? Если да, то как мне это сделать?

EXAMPLE:
(from trade in CrudeBalancedList
 where trade.Date.Month == monthIndex
 select trade).Update(
 trade => trade.Buy += optionQty);
4b9b3361

Ответ 1

Хотя linq не предназначен для обновления списков неизменяемых данных, он очень удобен для получения элементов, которые вы хотите обновить. Думаю, для вас это будет:

(from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).ToList().ForEach( trade => trade.Buy += optionQty);

Ответ 2

Я не уверен, что это лучший способ, но позволит вам обновить элемент из списка.

Объект проверки:

 public class SomeClass {
        public int Value { get; set; }
        public DateTime Date { get; set; }
    }

Метод расширения:

public static class Extension {
        public static void Update<T>(this T item, Action<T> updateAction) {
            updateAction(item);
        }
    }

Тест:

public void Test()
{
    // test data
    List<SomeClass> list = new List<SomeClass>()
    {
        new SomeClass {Value = 1, Date = DateTime.Now.AddDays(-1)},
        new SomeClass {Value = 2, Date = DateTime.Now },
        new SomeClass {Value = 3, Date = DateTime.Now.AddDays(1)}
    };
    // query and update
    (from i in list where i.Date.Day.Equals(DateTime.Now.Day) select i).First().Update(v => v.Value += 5);

    foreach (SomeClass s in list) {
        Console.WriteLine(s.Value);
    }
}

Ответ 3

Итак, вы ожидаете получить здесь один результат. В этом случае вы можете использовать метод SingleOrDefault:

var record =
    (from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).SingleOrDefault();

if (record != null)
    record.Buy += optionQty;

Обратите внимание, что метод SingleOrDefault ожидает, что оно будет возвращено ровно одно или нулевое (как строка в таблице для некоторого уникального первичного ключа). Если возвращается более одной записи, метод генерирует исключение.

Ответ 4

Чтобы создать такой метод, вы должны начать с его прототипа:

public static class UpdateEx {
    public void Update(this IEnumerable<T> items, 
                       Expression<Action> updateAction) {
    }
}

Это легкая часть.

Жесткая часть будет скомпилировать Expression<Action> в операторе обновления SQL. В зависимости от того, сколько синтаксиса вы хотите поддерживать, такая сложность компилятора может варьироваться от тривиального до невозможного.

Пример компиляции выражений Linq см. в TableQuery классе проект sqlite-net.