为什么Entity Framework没有提供DeleteAsync或AddAsync方法?

8
我刚刚注意到 EF(这里使用版本 5)没有提供 DeleteAsync()/AddAsync()。我还注意到像这样的项目:https://github.com/zzzprojects/EntityFramework-Plus,作为一种事后的想法提供了 DeleteAsync()。为什么 EF 没有默认提供 DeleteAsync() 呢?只是好奇。
补充说明:正如 EF-Plus 的维护者指出的那样,我提到的 'DeleteAsync' 版本在某种意义上与 EF 的 'Delete'/'DeleteAsync' 不同,前者操作的是针对将要在数据库/数据库服务器上匹配的元素的查询,而 EF 的 Delete 操作的是已经在 'Delete()' 调用之前检索到的元素。尽管这些方法的签名存在差异,但我的问题所引发的原始关注仍然具有其价值。

4
它确实提供了“删除(Remove)”和“保存更改异步(SaveChangesAsync)”。 - DavidG
2
当您在EF中执行RemoveAddUpdate操作时,更改不会保存,直到您运行SaveChanges。它有其异步模拟SaveChangesAsync - Ivan Gritsenko
1
嗯...我从未使用过那个特定的库,但是看着他们的DeleteAsync实现 - 你在这里得不到任何有用的东西。观看MSDN关于异步“库方法不应该欺骗”的视频。那个库中的代码确实如此。 - Matt Johnson-Pint
1
这里向库的作者发了一个提示:https://github.com/zzzprojects/EntityFramework-Plus/issues/131 - Matt Johnson-Pint
那个完整的视频系列非常惊人,如果你真的想学习如何正确地使用async/await。 - Matt Johnson-Pint
显示剩余2条评论
3个回答

9
观看了MattJohnson提供的非常启发性资料,以及通过反射调查Delete操作的实现后,我推测没有提供DeleteAsync()的原因是删除会在单个工作单元实例生命周期内改变数据库。
如果有人通过Task.Run()(即没有真正的异步实现)提供了“DeleteAsync()”操作,这将有效地通过反模式诱导幻觉,因为开发人员会使用这种API,认为他们享受到了“真正异步”的好处,但实际上他们不会,他们只会遭受不必要的开销,例如“await Task.Run(() => context.Foo.Delete(x))”,而根本没有享受任何好处。
简而言之:EF团队不提供“DeleteAsync()”/“AddAsync()”的底线解释就是“异步方法不应该说谎”(正如MattJohnson所指出的),而“DeleteAsync()”/“AddAsync()”会因为EF在撰写本文时的当前实现而被绑定说谎。

6

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

在 Entity Framework 中,AddRemove 方法与本库中的 Delete 方法有很大的区别。

Add/Remove

Add 方法仅向 ChangeTracker 添加实体,而 Remove 方法仅将 EntityState 更改为 "Deleted"。

正如 @Ivan 指出的那样,Remove 不会直接将更改保存到数据库中,直到您调用 SaveChangesSaveChangesAsync 方法。

Delete

此功能可删除数据库中的行,而无需在上下文中加载实体。

根据要删除的行数,调用此方法可能需要相当长的时间。

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

正如 @Matt 指出的那样,该库目前使用 Task.Run 而不是真正的异步操作,这将得到修复。


3
所有答案的要点都是,Remove()方法不是一项耗时操作,因为它只会改变跟踪器中的一个简单状态,而其他对应方法如Find()则需要访问数据库,这将是一个耗时的过程。另一方面,像AddAsync()这样的方法是根据其注释进行设计的:

此方法只是异步的,以便允许特殊值生成器(例如'Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo'所使用的值生成器)异步访问数据库。对于所有其他情况,应使用非异步的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接