【问题标题】:Create a single Query from EF 4.0 to SQL Server 2008 R2 instead of multiple queries创建从 EF 4.0 到 SQL Server 2008 R2 的单个查询,而不是多个查询
【发布时间】:2014-05-26 03:24:04
【问题描述】:

在以下代码中,将针对数据库运行多个查询以一次插入一行。

EF 导致多次数据库旅行: 当我调用 c.SaveChanges 时,EF 4.0 将对数据库运行多个 UPDATE 语句,但每次数据库行程只会执行一个 UPDATE。这意味着如果我们有 1000 条由 EF 4.0 生成的 UPDATE 语句,那么我们最终将进行 1000 次数据库访问,在我看来,这不是一个好的和最优的数据方法。

有没有什么方法可以让 EF 4.0 在一次数据库行程中为所有记录更新运行一个批处理查询? 如果我能获得 UPDATE 查询(我的意思是 SQL 查询),也许可以对于每个记录更新,那么我可以将所有这些查询放入单个批处理查询并将批处理查询发送到数据库,但我不知道是否可以在 EF 4.0 中获取每个记录的 UPDATE 查询。

 public void SaveVendorOrders(int vendorId, int parentVendorId, string tag,
                              string desc, int productSegment, int productCategory)     
 {  
  using (Vendor c = new Vendor())
        {
            var query = (from p in c.Orders
                         where (p.VendorID == vendorId ||
                                p.ParentVendorID == parentVendorId)
                         select p);

            if (query.ToList().Count() > 0)
            {
                for (int i = 0; i <= query.ToList().Count() - 1; i++)
                {
                    query.ToList()[i].OrderTag = tag;
                    query.ToList()[i].OrderDescription = desc;
                    query.ToList()[i].ProductSegment = productSegment;
                    query.ToList()[i].ProductSegmentCategory = productCategory;
                }

                c.SaveChanges();
            }
        }
 }

编辑 1:

正如 SJuan76 和 Hamlet Hakobyan 所指出的,重复调用 ToList 会重复执行一个查询。但即使这可以通过清理代码来解决,所以 ToList 只被调用一次,我的问题仍然存在:如何将多个更新组合成一个批量更新查询?

【问题讨论】:

  • 哇……哇。你知道每个ToList() 至少是一个 SQL 查询,不是吗?
  • 你的意思是 query.ToList 应该在这个方法中只调用一次?我现在明白了。这是一些在现有应用程序中导致许多性能问题的代码,我被赋予了提高其性能的任务。我是 EF 的新手,所以从不知道 query.ToList() 会对数据库执行查询,但现在很有意义。
  • 没有冒犯,但这是不使用 EF 的一个很好的例子。
  • @Kunukn,我在这点上与你 100% 同意。为什么要进行多次数据库访问,尤其是在未来有可能进行数千次更新的情况下。如果它总是大约 10 个左右,那么我会很好,但在这种情况下,供应商可能在数据库中有数千个订单,这意味着数千次数据库访问。

标签: c# entity-framework-4


【解决方案1】:

旨在延迟执行的查询。它确实会执行您枚举查询的乳清,或者,例如,调用ToList()。为避免多次枚举,您必须调用 ToList() 一次调用您方法中的内存数据。

using (Vendor c = new Vendor())
{
  var query = (from p in c.Orders
               where (p.VendorID == vendorId ||
                      p.ParentVendorID == parentVendorId)
               select p).ToList();

  if (query.Count() > 0)
  {
      for (int i = 0; i <= query.Count() - 1; i++)
      {
          query[i].OrderTag = tag;
          query[i].OrderDescription = desc;
          query[i].ProductSegment = productSegment;
          query[i].ProductSegmentCategory = productCategory;
      }

      c.SaveChanges();
  }
}

【讨论】:

  • 谢谢。这是完全合理的,我认为这可能会导致用户报告的性能问题,尤其是在供应商有数千个订单的情况下。
  • 我将多个更新合并到一个查询中的问题仍未得到解答。你知道这是怎么做到的吗?
  • combining multiple updates into a single query 是什么意思?能详细解释一下吗?
  • 当我调用 c.SaveChanges 时,它会导致多个更新查询被发送到数据库,但一次一个。所以这会导致很多数据库访问。我只想进行一次数据库之旅,一次发送所有 UPDATE 查询。您可以在我的原始帖子的“EF 导致多次数据库旅行”下看到我对此的解释。
  • @Sunil 你想要的是批量更新,也许这可以帮助你stackoverflow.com/questions/12751258/batch-update-delete-ef5或者搜索实体框架批量更新,或者支持批量更新的轻量级ORM
猜你喜欢
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
相关资源
最近更新 更多