2014-10-07 65 views
0

所以我有這樣的代碼:更換的foreach使用LINQ表達

foreach (var optionValues in productOption.ProductOptionValues) 
{ 
    if (optionValues.ProductOptionValueID > 0) 
    { 
    unitOfWork.ProductContext.Entry(optionValues).State = EntityState.Modified; 
    } 
    else 
    { 
    unitOfWork.ProductContext.Entry(optionValues).State = EntityState.Added; 
    } 
} 

這樣做的代碼審查是我應該看看使用LINQ做到這一點。

有人可以請我指出一個資源,可以解釋使用LINQ來改變對象的屬性?

+1

爲什麼你要linq不是foreach? – Grundy 2014-10-07 10:03:52

+0

避免foreach爲什麼如此? – Reniuz 2014-10-07 10:04:45

+1

我想看看在這裏使用LINQ的理由。 LINQ是* query *語法,所以在你的情況下並不適合。然而,這裏說的是一個簡單的[ForEach](http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet)擴展,你可以用它來做到這一點。 – James 2014-10-07 10:05:20

回答

7

LINQ用於查詢。你是修改值,所以foreach是完全正確的。

8

你沒有。就那麼簡單。

代碼審查這是我應該看看使用LINQ來做到這一點,並避免foreach。

告訴密碼審查他他錯了。 Lin Q用於Q uerying數據。你是更新數據。留在你的foreach循環中,沒關係。

0

唯一合理的使用LINQ在這裏(這取決於ProductOptionValues類型)是使用Where,基本上取代您if語句來篩選結果,但它不是比你當前的代碼更好:

foreach (var option in productOption.ProductOptionValues.Where(x => x.ProductOptionValueID > 0) 
    unitOfWork.ProductContext.Entry(optionValues).State = EntityState.Modified; 

foreach (var option in productOption.ProductOptionValues.Where(x => x.ProductOptionValueID <= 0) 
    unitOfWork.ProductContext.Entry(optionValues).State = EntityState.Added; 
1

你能做的最好是這樣的:

var query = 
    from optionValues in productOption.ProductOptionValues 
    select new 
    { 
     entry = unitOfWork.ProductContext.Entry(optionValues), 
     value = optionValues.ProductOptionValueID > 0 
      ? EntityState.Modified 
      : EntityState.Added 
    }; 

foreach (var x in query) 
{ 
    x.entry.State = x.value; 
} 

但我不認爲這真的讓你在可讀性方面多。

-1

假設productOption.ProductOptionValues是一個IList <>()(如果它不是,你可能需要做.ForEach前.ToList()),這將是這樣的:

productOption.ProductOptionValues.ForEach(x => 
    unitOfWork.ProductContext.Entry(x).State = (
     (x.ProductOptionValueID > 0) ? EntityState.Modified : EntityState.Added) 
) 

...但我不認爲這真的是一個改進。事實上恰恰相反。

真的,不要這樣做。

+2

嚴格來說,這甚至不是LinQ,因爲'ForEach'是'List '的一種方法,而不是'System.Linq'的擴展方法。 – nvoigt 2014-10-07 10:26:19

-1

整蠱,只是爲了幽默,有可能在幾個方面,如:

var sum = productOption.ProductOptionValues.Select(
     optionValues => unitOfWork.ProductContext.Entry(optionValues).State = (optionValues.ProductOptionValueID > 0 ? EntityState.Modified : EntityState.Added).Sum(); 
0

你不應該使用LINQ的ForEach擴展。讓我解釋爲什麼:

LINQ foreach違反了所有其他序列操作符都基於的函數式編程原則。 顯然,調用此方法的唯一目的是引起副作用。表達式的目的是計算一個值,而不是引起副作用。 陳述的目的是引起副作用。這個東西的調用網站看起來會非常像一個表達式

第二個原因是使用它會爲您的代碼添加零代表值。這樣做可以讓你重寫這個非常清晰的代碼:

foreach(Foo foo in foos){涉及foo的語句; }

到這個代碼:

foos.ForEach((美孚FOO)=> {聲明涉及FOO;});

它使用幾乎完全相同的字符,順序稍有不同。然而,第二個版本更難理解,難以調試,並且引入了閉包語義,因此可能以微妙的方式改變對象的生命週期。

以上是部分摘自Eric Lippert的博客文章。閱讀全文here

更重要的是擴展已經由BCL團隊除去在Windows 8:

List.ForEach已在Metro風格應用程序被刪除。儘管該方法看起來很簡單,但當列表被傳遞給ForEach的方法突變時,它有許多潛在的問題。

相反,建議您只使用一個foreach循環。