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

发布于 2024-10-18 01:33:07 字数 772 浏览 0 评论 0原文

在运行更新之前,我需要重置特定表中的布尔字段。 该表可能有 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 但尚未实施,但想知道是否有更标准的方法。

为了保持在这个项目的限制范围内,我们不能使用存储过程或直接在上下文的 ExecuteStoreCommand 参数中编写 TSQL,我相信您可以做到。

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

任何想法,

提前致谢。 利亚姆

I need to reset a boolean field in a specific table before I run an update.
The table could have 1 million or so records and I'd prefer not to have to have to do a select before update as its taking too much time.

Basically what I need in code is to produce the following in TSQL

update tablename 
set flag = false 
where flag = true

I have some thing close to what I need here http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx
but have yet to implement it but was wondering if there is a more standard way.

To keep within the restrictions we have for this project, we cant use SPROCs or directly write TSQL in an ExecuteStoreCommand parameter on the context which I believe you can do.

I'm aware that what I need to do may not be directly supported in EF4 and we may need to look at a SPROC for the job [in the total absence of any other way] but I just need to explore fully all possibilities first.
In an EF ideal world the call above to update the flag would be possible or alternatively it would be possible to get the entity with the id and the boolean flag only minus the associated entities and loop through the entity and set the flag and do a single SaveChanges call, but that may not be the way it works.

Any ideas,

Thanks in advance.
Liam

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

剩一世无双 2024-10-25 01:33:07

我会去找利益相关者,他介绍了不直接使用 SQL 或 SPproc 的限制,并向他展示以下事实:

  • ORM(如实体框架)中的更新是这样工作的:加载对象、执行修改、保存对象。这是唯一有效的方法。
  • 显然,在您的情况下,这意味着分别加载 1M 实体并执行 1M 更新(EF 没有命令批处理 - 每个命令在其自己的 DB 往返中运行) - 通常绝对无用的解决方案。
  • 您提供的示例看起来非常有趣,但它是针对 Linq-To-Sql 的。不适用于实体框架。除非您实现它,否则您无法确定它是否适用于 EF,因为 EF 中的基础设施要复杂得多。因此,您可能会花费几个人天的时间来执行此操作,但没有任何结果 - 这应该得到利益相关者的批准。
  • 使用 SPproc 或直接 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 或两个数据库连接,并且在事务 = 分布式事务和另一个性能影响的情况下。

I would go to stakeholder who introduced restirctions about not using SQL or SProc directly and present him these facts:

  • Updates in ORM (like entity framework) work this way: you load object you perform modification you save object. That is the only valid way.
  • Obviously in you case it would mean load 1M entities and execute 1M updates separately (EF has no command batching - each command runs in its own roundtrip to DB) - usually absolutely useless solution.
  • The example you provided looks very interesting but it is for Linq-To-Sql. Not for Entity framework. Unless you implement it you can't be sure that it will work for EF, because infrastructure in EF is much more complex. So you can spent several man days by doing this without any result - this should be approved by stakeholder.
  • Solution with SProc or direct SQL will take you few minutes and it will simply work.
  • In both solution you will have to deal with another problem. If you already have materialized entities and you will run such command (via mentioned extension or via SQL) these changes will not be mirrored in already loaded entities - you will have to iterate them and set the flag.
  • Both scenarios break unit of work because some data changes are executed before unit of work is completed.

It is all about using the right tool for the right requirement.

Btw. loading of realted tables can be avoided. It is just about the query you run. Do not use Include and do not access navigation properties (in case of lazy loading) and you will not load relation.

It is possible to select only Id (via projection), create dummy entity (set only id and and flag to true) and execute only updates of flag but it will still execute up to 1M updates.

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();
}

Moreover it will only work in empty object context (or at least no entity from updated table can be attached to context). So in some scenarios running this before other updates will require two ObjectContext instances = manually sharing DbConnection or two database connections and in case of transactions = distributed transaction and another performance hit.

少跟Wǒ拽 2024-10-25 01:33:07

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

Make a new EF model, and only add the one Table you need to make the update on. This way, all of the joins don't occur. This will greatly speed up your processing.

深爱不及久伴 2024-10-25 01:33:07
ObjectContext.ExecuteStoreCommand ( _
    commandText As String, _
    ParamArray parameters As Object() _
    ) As Integer

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

编辑
抱歉,没有把帖子看完。

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

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

Edit
Sorry, did not read the post all the way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文