EF4更新表中所有行的值而不进行选择

时间:2011-02-19 00:04:15

标签: c# sql sql-server entity-framework-4

我需要在运行更新之前重置特定表中的布尔字段。 该表可能有100万左右的记录,我不希望在更新之前必须进行选择,因为它花费了太多时间。

基本上我在代码中需要的是在TSQL中生成以下内容

update tablename 
set flag = false 
where flag = true

我有一些接近我需要的东西http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx 但还没有实现它,但想知道是否有更标准的方法。

为了保持我们对这个项目的限制,我们不能使用SPROC或直接在我认为你可以做的上下文的ExecuteStoreCommand参数中编写TSQL。

我知道我需要做的事情可能不会直接支持EF4,我们可能需要查看SPROC的工作[完全没有任何其他方式]但我只需要全面探索可能性首先。 在EF理想世界中,上述调用更新标志是可能的,或者可能有可能获得具有id和布尔标志的实体仅减去关联实体并循环通过实体并设置标志并执行单个操作SaveChanges调用,但这可能不是它的工作方式。

任何想法,

提前致谢。 利安

3 个答案:

答案 0 :(得分:4)

我会去利益相关方介绍有关不直接使用SQL或SProc的重新提交并向他介绍这些事实:

  • ORM中的更新(如实体框架)以这种方式工作:加载对象执行修改后保存对象。这是唯一有效的方法。
  • 显然,在你的情况下,它意味着加载1M实体并分别执行1M更新(EF没有命令批处理 - 每个命令都在自己的往返数据库中运行) - 通常是绝对无用的解决方案。
  • 您提供的示例看起来非常有趣,但它适用于Linq-To-Sql。不适用于Entity框架。除非您实现它,否则您无法确定它是否适用于EF,因为EF中的基础结构要复杂得多。所以你可以花几个人的日子这样做而没有任何结果 - 这应该得到利益相关者的批准。
  • 使用SProc或直接SQL的解决方案将花费您几分钟,它将只是工作。
  • 在这两个解决方案中,您将不得不处理另一个问题。如果您已经有物化实体并且您将运行此类命令(通过提到的扩展或通过SQL),则这些更改将不会在已加载的实体中进行镜像 - 您必须迭代它们并设置标志。
  • 这两种情况都会破坏工作单元,因为在工作单元完成之前会执行一些数据更改。

这就是为正确的要求使用正确的工具。

顺便说一下。可以避免加载已调整的表格。它只是关于你运行的查询。不要使用Include,也不要访问导航属性(如果是延迟加载),则不会加载关系。

可以只选择Id(通过投影),创建虚拟实体(仅设置id和标志为true)并仅执行标志更新,但它仍将执行最多1M次更新。

using(var myContext = new MyContext(connectionString))
{
  var query = from o in myContext.MyEntities
              where o.Flag == false
              select o.Id;
  foreach (var id in query)
  {
    var entity = new MyEntity
      {
        Id = id,
        Flag = true
      };
    myContext.Attach(entity);
    myContext.ObjectStateManager.GetObjectStateEntry(entity).SetModifiedProperty("Flag");
  }

  myContext.SaveChanges();
}

此外,它只能在空对象上下文中工作(或者至少没有来自更新表的实体可以附加到上下文中)。因此,在某些情况下运行此操作之前,其他更新将需要两个ObjectContext实例=手动共享DbConnection或两个数据库连接,并且在事务=分布式事务和另一个性能命中的情况下。

答案 1 :(得分:0)

创建一个新的EF模型,只添加进行更新所需的一个表。这样,所有连接都不会发生。这将大大加快您的处理速度。

答案 2 :(得分:0)

ObjectContext.ExecuteStoreCommand ( _
    commandText As String, _
    ParamArray parameters As Object() _
    ) As Integer

http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.executestorecommand.aspx

修改
对不起,没有一直看完帖子。