Linq to objects Update

百般思念 提交于 2019-12-11 11:46:42

问题


Im using Linq - objects and I need to do an update. I've been looked around for a while but not really found anything that matches.

So for arguments sake I have 2 simple List's, both with a key so I can use join happily.

I cant find a simple way to update results from obj2 into obj1.

for simple updates I'm currently doing this:

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

And that all works well and dandy. However if I add into the mix my second table and I want to replace newValue with obj2. then I get problems.

Primarily because I then switch to a full linq statement like:

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

Its here im getting stuck.

If anybody could help I would be extremly grateful! Thanks in advance.


回答1:


What you're trying to do here isn't a particularly good thing to do with Linq as Linq is meant to be for querying data and not updating it. Your Select statement is relying on side-effects to perform the update. This generally should be avoided.

However, you can still do what you want.

To start with, I re-arranged your query as:

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

Then I refactored it as such:

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

This still has the side-effect, but I made it more explicit (and hopefully more readable).

Given this refactoring, the UPDATE query involving the two lists becomes:

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

If you wanted to do this without side-effects, I would suggest the following:

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

You might not like this syntax, so you could easily write quick extension method on IEnumerable<Action> to invoke the actions and would make the code look like this:

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

I hope this helps.



来源:https://stackoverflow.com/questions/3658028/linq-to-objects-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!