it-swarm.com.ru

Как обновить элемент со списком, используя LINQ и C #

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

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

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

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

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

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

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

 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);
    }
}
4
Fernando

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

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

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

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

1
Dan Tao

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

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

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

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

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

0
Frank Krueger