Как обновить элемент со списком, используя LINQ и C # - PullRequest
13 голосов
/ 15 марта 2010

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

Будет ли создание метода расширения Обновления работать? Если так, как бы я поступил так?

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

Ответы [ 4 ]

30 голосов
/ 15 марта 2010

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

(from trade in CrudeBalancedList
    where trade.Date.Month == monthIndex
    select trade).ToList().ForEach( trade => trade.Buy += optionQty);
4 голосов
/ 15 марта 2010

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

Тестовый объект:

 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);
    }
}
1 голос
/ 15 марта 2010

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

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

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

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

0 голосов
/ 15 марта 2010

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

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

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

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

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

...