Обновление Linq к объектам - PullRequest
       5

Обновление Linq к объектам

1 голос
/ 07 сентября 2010

Я использую Linq - объекты, и мне нужно сделать обновление.Некоторое время я осматривался, но не нашел ничего подходящего.

Итак, ради аргументов, у меня есть 2 простых списка, оба с ключом, поэтому я могу счастливо использовать соединение.

Я не могу найти простой способ обновить результаты из obj2 в obj1.

для простых обновлений, в настоящее время я делаю это:

string newValue = "something";
var items = obj1.Where(w => w.ID == iKey).Select(c => {c.<property> = newValue; return c; }).ToArray();

И это все работает хорошо и денди.Однако, если я добавлю в микс свою вторую таблицу и захочу заменить newValue на obj2.тогда у меня возникают проблемы.

Прежде всего потому, что я затем переключаюсь на полный оператор linq, такой как:

var UPDATE = from o1 in obj1
             join o2 in obj2 on o1.key equals o2.key
             select ....;

Здесь я застреваю.

Если кто-нибудь может помочь, я быбудь крайне благодарен!Заранее спасибо.

1 Ответ

2 голосов
/ 09 сентября 2010

То, что вы пытаетесь сделать здесь, не особенно полезно для Linq, поскольку Linq предназначен для запроса данных, а не для их обновления.Ваше заявление Select полагается на побочные эффекты для выполнения обновления.Этого, как правило, следует избегать.

Однако вы все равно можете делать то, что хотите.

Для начала я перестроил ваш запрос следующим образом:

var items =
    obj1
    .Where(w => w.Key == iKey)
    .Select(c => { c.Value = newValue; return c; })
    .ToArray();

ТогдаЯ рефакторинг это так:

Func<Obj, string, Obj> update =
    (c, v) => { c.Value = v; return c; };

var items = (from w in obj1
             where w.Key == iKey
             select update(w, newValue)).ToArray();

Это все еще имеет побочный эффект, но я сделал его более явным (и, надеюсь, более читабельным).

Учитывая этот рефакторинг, UPDATEзапрос, включающий два списка, выглядит следующим образом:

var UPDATE = (from o1 in obj1
              join o2 in obj2 on o1.Key equals o2.Key
              select update(o1, o2.Value)).ToArray();

Если вы хотите сделать это без побочных эффектов, я бы предложил следующее:

var items = from w in obj1
            where w.Key == iKey
            select (Action)(() => w.Value = newValue);

Array.ForEach(items.ToArray(), a => a());

var UPDATE = from o1 in obj1
             join o2 in obj2 on o1.Key equals o2.Key
             select (Action)(() => o1.Value = o2.Value);

Array.ForEach(UPDATE.ToArray(), a => a());

Вам может не понравиться этот синтаксис, поэтомуВы можете легко написать быстрый метод расширения для IEnumerable<Action> для вызова действий и сделать код таким:

(from w in obj1
 where w.Key == iKey
 select (Action)(() => w.Value = newValue)).Invoke();

(from o1 in obj1
 join o2 in obj2 on o1.Key equals o2.Key
 select (Action)(() => o1.Value = o2.Value)).Invoke();

Надеюсь, это поможет.

...