gpt4 book ai didi

wpf - 长期存在的 Entity Framework 上下文 - 避免数据完整性问题的最佳实践

转载 作者:行者123 更新时间:2023-12-04 19:16:40 25 4
gpt4 key购买 nike

作为一个非常初级的场景,让我们来看看这两个操作:

UserManager.UpdateFirstName(int userId, string firstName)
{
User user = userRepository.GetById(userId);
user.FirstName = firstName;
userRepository.SaveChanges();
}

InventoryManager.InsertOrder(Order newOrder)
{
orderRepository.Add(newOrder);
orderRepository.SaveChanges();
}

我只在 web 项目中使用过 EF,并且严重依赖 web 的无状态特性。对于每个请求,我都会将上下文的新副本注入(inject)到我的业务层外观对象(服务、管理器,无论您想如何称呼它们)中,所有业务管理器共享同一个 EF 上下文实例。目前我正在开发一个 WPF 项目,我正在将业务经理以及随后他们直接使用的存储库注入(inject)到 View 模型中。

假设用户在一个复杂的屏幕上,并且他的第一个按钮单击调用了 UpdateFirstName() 方法。让我们假设 SaveChanges() 因任何原因而失败。他们的第二次按钮单击将调用 InsertOrder() 方法。

在 Web 上,这不是问题,因为操作 #2 的上下文与操作 #1 使用的上下文无关(新的 http 请求)。然而,在桌面上,这两个操作的上下文相同。问题在于用户的名字已被修改,因此由上下文跟踪。即使最初的 SaveChanges() 没有使用(比如当时数据库不可用),调用 SaveChanges() 的第二个操作不仅会插入新订单,还会更新用户的名字。在几乎所有原因中,这都是不可取的,因为用户早已忘记了他们的第一个操作无论如何都失败了。

这显然是一个愚蠢的例子,但我总是倾向于遇到这种情况,我希望我可以为每个用户操作从一个新的上下文重新开始,而不是更长的生命周期(对于 WPF 窗口的生命周期例)上下文。

大家是怎么处理这些情况的呢?

最佳答案

当来自直接访问数据库的临时桌面应用程序时,这是一个非常真实的询问。

似乎符合 ORM 理念的答案是拥有一个与屏幕具有相同生命周期的上下文。
本质上,数据上下文是一个工作单元实现。对于 Web 应用程序,这显然是请求并且运行良好。

对于桌面应用程序,您可以将上下文绑定(bind)到屏幕,或者可能绑定(bind)到编辑操作(在加载和按下“保存”之间)。只读操作可能有一次性上下文(在必要时使用 ID 重新加载对象,例如在网格中按下“删除按钮”时)。
如果您想了解其他用户的修改(关系集合在首次加载时被缓存),请忘记跨越整个应用程序生命周期的上下文。
还要忘记在不同窗口之间直接共享 EF 实体,因为这有效地使其成为应用程序范围内的长期上下文。

因此,在我看来,ORM 倾向于在桌面应用程序上强制执行类似 Web 的设计。恐怕没有真正的解决方法。
并不是说它本身就是一件坏事。如果要在多个实例之间共享,通常不应在桌面级别攻击数据库。在这种情况下,您将使用服务层,EF 将在其元素中,您的问题将转移到“服务上下文”......

关于wpf - 长期存在的 Entity Framework 上下文 - 避免数据完整性问题的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8659036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com