用LINQ表达式替换foreach

时间:2014-10-07 10:01:40

标签: c# 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更改对象属性的资源吗?

7 个答案:

答案 0 :(得分:8)

你不是。就这么简单。

  

对此的代码审查是我应该考虑使用LINQ来做到这一点并避免使用foreach。

告诉代码审稿人他错了。 Lin Q 用于 Q 重要数据。您正在更新数据。保持你的foreach循环,没关系。

答案 1 :(得分:7)

LINQ用于查询。您正在修改值,因此foreach完全没问题。

答案 2 :(得分: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;
}

但我认为这在可读性方面确实给你很多。

答案 3 :(得分: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;

答案 4 :(得分:0)

您不应该使用LINQ ForEach扩展。让我解释一下原因:

LINQ foreach违反了所有其他序列运算符所基于的函数式编程原则。 显然,调用此方法的唯一目的是引起副作用。表达式的目的是计算一个值,而不是引起副作用。 声明的目的是产生副作用。这个东西的调用网站看起来很像表达式

第二个原因是使用它会为代码增加零代表值。这样做可以让你重写这个非常清晰的代码:

  

foreach(foo foo in foos){声明涉及foo; }

进入此代码:

  

foos.ForEach((Foo foo)=&gt; {声明涉及foo;});

使用几乎完全相同的字符,顺序略有不同。然而第二个版本更难理解,更难调试,并引入了闭包语义,从而可能以微妙的方式改变对象的生命周期。

以上是Eric Lippert的博客文章的摘要。阅读完整的帖子here

更多内容已被Windows 8中的BCL团队删除:

List.ForEach已在Metro风格应用中删除。虽然这个方法看起来很简单,但是当列表被传递给ForEach的方法变异时,它会遇到许多潜在的问题。

相反,建议您只使用foreach循环。

答案 5 :(得分:-1)

假设productOption.ProductOptionValues是一个IList&lt;&gt;()(如果你不需要在.ForEach之前做一个.ToList()),它将是这样的:

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

......但我不认为这真的是一种进步。事实恰恰相反。

真的,不要这样做。

答案 6 :(得分:-1)

Tricky,只是为了幽默,它可以通过多种方式实现,例如:

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