2014-10-07 64 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循环。