2010-09-07 55 views
1

我使用Linq - 对象,我需要做一个更新。我一直环顾四周,但没有发现任何匹配的东西。Linq到对象更新

因此,为了参数的缘故,我有两个简单的List,都带有一个键,所以我可以愉快地使用连接。

我找不到一个简单的方法来将obj2的结果更新为obj1。

简单更新目前,我正在做这个:

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

而这一切运作良好和花花公子。 但是,如果我添加到混合我的第二个表,我想用obj2替换newValue。那么我会遇到问题。

主要是因为我再切换到全LINQ声明,如:

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

它的IM在这里被卡住。

如果有人能帮助我,我会非常感激! 在此先感谢。

回答

2

你在这里试图做的并不是一件特别好的事情,因为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(); 

我希望这会有所帮助。

+0

是的,更新扩展方法会使代码更自然地阅读,如在“items.Where(...)。Update(...)” – 2010-09-09 07:43:17

+0

Thankyou中详细回答。我会非常严厉地告诉你,让你知道。 – DubMan 2010-09-09 11:22:27

+0

@DubMan - 已经很糟糕了吗? LOL – Enigmativity 2011-11-09 10:43:12