2010-09-07 56 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