【问题标题】:Entity Framework doesn't provide DeleteAsync or AddAsync. Why?实体框架不提供 DeleteAsync 或 AddAsync。为什么?
【发布时间】:2017-02-23 17:39:43
【问题描述】:

我刚刚注意到 EF(此处使用版本 5)不提供 DeleteAsync()/AddAsync()。我还注意到像这样的项目:

https://github.com/zzzprojects/EntityFramework-Plus

请在事后提供DeleteAsync()。为什么 EF 不提供开箱即用的DeleteAsync()?只是好奇。

附录:正如 EF-Plus 的维护者所指出的,我提到的“DeleteAsync”风格与 EF 的“Delete”/“DeleteAsync”有些不同,因为前者在查询目标元素上操作 在 db/db-server 上匹配,而 EF 的 Delete 对 在调用“Delete()”之前已经检索到的元素进行操作。尽管这些方法的签名存在差异,但我的问题提出的最初关注仍然存在。

【问题讨论】:

标签: c# sql entity-framework


【解决方案1】:

免责声明:我是Entity Framework Plus的所有者

Entity Framework 中的 Add && Remove 和我的库中的 Delete 之间存在巨大差异。

添加/删除

Add 方法只会将实体添加到 ChangeTracker,而 Remove 方法只会将 ChangeTracker 中的 EntityState 更改为“Deleted”。

正如@Ivan 指定的那样,Remove 不会在您调用SaveChangesSaveChangesAsync 之前将更改直接保存在数据库中

删除

此功能从数据库中删除行而不在上下文中加载实体。

调用此方法可能需要相当长的时间,具体取决于将在数据库中删除的行数。

因此,在这里提供DeleteAsync 方法是有意义的。

正如@Matt 指定的那样,该库当前使用Task.Run 而不是真正的异步,这最终将得到修复。

【讨论】:

    【解决方案2】:

    在观看了 MattJohnson 提供的非常有启发性的材料并在使用反射探索了 Delete 的实现之后,我推测未提供 DeleteAsync() 背后的原因是 delete 导致数据库在单个单元内更改-工作实例生命周期。

    如果有人通过 Task.Run() 提供了“DeleteAsync()”操作(又名没有真正的异步实现),这将有效地通过反从某种意义上说,开发人员会使用这种 API 并认为他们享受“真正异步”的好处,但实际上他们不会 - 他们只会遭受不必要的开销 ala 'await Task. Run(() => context.Foo.Delete(x))' 没有任何好处。

    TL;DR:为什么 EF 的人不提供“DeleteAsync()”/“AddAsync()”的底线解释是“异步方法不应该撒谎”(正如 MattJohnson 指出的那样)和“DeleteAsync ()'/'AddAsync()' 在撰写本文时,鉴于 EF 的当前实现,势必存在。

    【讨论】:

      【解决方案3】:

      我认为所有答案的要点是,Remove() 方法不是一个耗时的操作,它只改变跟踪器中的一个简单状态,而其他对应物例如Find() 需要 ping 数据库,这将是一个耗时的过程。
      另一方面,像AddAsync() 这样的方法是按照它的评论说的:

      此方法是异步的,仅允许特殊值生成器,例如 由“Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo”使用, 异步访问数据库。对于所有其他情况,非异步方法 应该使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多