首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将本地上下文中的实体与EF Core中的数据库中的实体进行比较?

如何将本地上下文中的实体与EF Core中的数据库中的实体进行比较?
EN

Stack Overflow用户
提问于 2022-02-09 22:29:10
回答 2查看 524关注 0票数 0

EF核心6和.NET 6。

假设我的所有实体都有一个LastUpdateAt属性,它是一个DateTime,每次添加或修改实体时都会更新该属性。

我从上下文中获得一个实体,并将其显示给用户(网页、WPF窗口等)。在某个时候,用户单击Save按钮。

在保存之前,我想检查实体是否已经被其他人更新了,因为我得到了我的副本。然而,我正在努力寻找如何做到这一点。

如果我查询上下文,它只会返回我已经拥有的实体(包括我的用户所做的任何更改)。

如果刷新该实体,它将覆盖上下文中的实体,从而丢失用户的更改。

如何检查数据库版本是否具有比上下文中的时间戳更新的时间戳?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-09 23:07:08

将讨论移到这里,因为我需要粘贴更长的文本。在这篇文章中,据说在SaveChanges()期间,如果数据库版本在同时被修改,它将抛出DbUpdateConcurrencyException。在该异常中,您拥有所有3个值,并且可以决定如何解决冲突:

解决并发冲突涉及将当前DbContext中的挂起的更改与数据库中的值合并。合并的值将根据应用程序的不同而有所不同,并且可能由用户输入指导。

有三组值可用于帮助解决并发冲突:

当前值是应用程序试图写入数据库的值。原始值是最初从数据库中检索的值,然后再进行任何编辑。数据库值是当前存储在数据库中的值。

票数 1
EN

Stack Overflow用户

发布于 2022-02-09 23:10:11

如果您正在加载一个实体,保持一个DbContext实例处于打开状态,更新该实体,然后保存到同一个DbContext实例,那么默认情况下,您依赖EF来管理并发性。这是在“最后的胜利”之后。您可以让EF通过在[ConcurrencyCheck]属性上添加LastUpdateAt或通过[Timestamp]使用行版本来管理并发性。如果基础数据已被更新,这将导致EF更新失败。从那以后,你必须决定如何处理它。

如果您想自己执行并发性检查,那么有几个选项。

  1. 使用分离实体或投影视图模型构造代码以缩短DbContext的生存期。这通常会给您的代码性能带来流动的好处,因为原始的更长寿命的DbContext可以很容易地找到导致膨胀的方法,或者在活得太久时积累“中毒”的实体。Automapper是一个很好的工具,您可以在这里使用ProjectTo获取视图模型,然后使用Map(source, destination)复制值。以这种方式加载数据(包括上次修改的at value ),进行更改,然后在保存时加载数据,验证修改后的at等,然后跨域复制值并保存。
  2. 在保存之前对DbContext实例进行范围检查。

代码语言:javascript
复制
private DateTime getFooLastUpdateAt(int fooId)
{
    using(var context = new AppDbContext())
    {
         var lastUpdateAt = context.Foos
             .Where(x => x.FooId == fooId)
             .Select(x => x.LastUpdateAt)
             .Single();
         return lastUpdateAt;
    }
}

这可以使用注入的DbContext工厂或类似的方法来创建DbContext实例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71057616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档