如何重用自跟踪实体?

发布于 2024-10-09 09:47:24 字数 1112 浏览 10 评论 0原文

在 STE 的无数问题中,我现在面临着这个问题,这应该是微不足道的,但事实并非如此:

为了简单起见,让我们假设一个标准发票、订单、产品场景。

假设我有一个非无状态(无论出于何种原因)层,它接收发票并为某些产品添加一些订单,然后将发票发送回其来源层。

这听起来很简单,但实际上是 STE 的一个问题,我没有找到简单的解决方案。问题是如何保留产品实体的集合以分配给订单。在我看来,我必须采用以下方式之一来完成此操作,这些方式都有主要缺点:

在数据库中查询我想要在发票实体中下的每个订单的产品实体。

缺点: 如果在多个订单中使用相同的产品,则当发票更改保存在数据库中时,EF 将引发异常,因为上下文中不允许相同产品密钥的多个实例。我可以确保多个订单中出现的产品仅查询一次,然后在订单之间共享,但这肯定会让事情变得复杂。

如果产品实体(或另一个领域场景中的等效实体)相当大,或者出于某种原因在应用程序层查询数据库中的产品是不切实际的,另一个缺点是性能。

在应用程序生命周期开始时查询数据库中的所有产品实体

如果您在用户应用程序中保留产品列表并且产品列表很少更改,那么这将是典型的场景。就我而言,我不想查询数据库,因为“产品”类型列表在应用程序的生命周期中永远不会改变,性能是一个重要问题,系统应该对数据库暂时不可用具有鲁棒性,所以我想要保留“产品”等效实体的缓存集合。

缺点:这里的主要缺点是将缓存的产品分配给新的订单实体将导致内存泄漏。原因是 STE 生成的“Fixup”方法会将事件处理程序连接到产品的 ChangeTracker,以便处理产品的级联删除。该事件处理程序将保持新订单和已连接的缓存产品,并累积在缓存生命周期内添加的所有订单。 解决方案可能是实现 STE 的某种“冻结”属性,这样不仅会禁用更改跟踪,而且即使在导航属性分配之后,实体和更改跟踪器的状态也将保持不变。这种“冻结”修改可能很难编写,因为 STE 代码具有很多副作用,使得它们难以修改。

创建产品实体克隆

这里,在应用程序生命周期开始时查询产品,但不是使用产品实体,而是在将产品分配给订单时进行克隆。这将解决内存泄漏问题,但需要实现和维护克隆。重写 STE .tt 脚本以支持克隆可能不会太难。尽管如此,实体上下文中的多个实体共享相同的密钥仍然存在问题。

Among countless problems with STEs I am now facing this one, which should be trivial, but is not:

For simplicity, lets assume a standard invoice, order, product scenario.

Lets say that I have a non-stateless (for whatever reason) tier that receives an invoice and adds some orders for some products before sending the invoice back to the tier it came from.

This sounds simple, but is actually a problem with STEs that I have found no simple solution for. The problem is how to keep a collection of product entities to assign to the orders. As I see it I would have to do it in one of these ways, that all have major drawbacks:

Query the database for a product entity for each order I want to place in the invoice-entity.

Drawbacks:
If the same product is used in several orders, EF will throw an exception, when the invoice changes are saved in the database, since multiple instances of the same product key is not allowed in the context. I could make sure that products occurring in multiple orders are only queried once and then shared among the orders, but it would definitely complicate things.

Another drawback is performance if the product entities (or equivalent entity in another domain scenario) are rather large or querying the database for products at the application tier is impractical for whatever reason.

Query the database for all product entities at the beginning of the application lifetime

This would be the typical scenario if you keep a list of products in a user application if the list of products rarely changes. In my case I don't want to query the database, since the "product" type list never changes in the lifetime of the application, performance is an important issue and the system should be robust to the database being temporarily unavailable, so I want to keep a cached collection of "product" equivalent entities.

Drawbacks: The major drawback here is that assigning cached products to new order entities will cause a memory leak. The reason for that is that the "Fixup" methods generated by the STE will hookup an event handler to the product's ChangeTracker in order to handle cascading deletions of a product. That event handler will keep the new order and the cached product connected accumulating all orders added for the lifetime of the cache.
A solution could be to implement some kind of "freeze" property of STEs, such that not only would change tracking be disabled, but the state of the entity and change tracker would remain unchanged even after navigation property assignments. Such a "freeze" modification could be difficult to write, since STE code comes with a lot of side effects making them hard to modify.

Create product entity clones

Here the products are being queried at the beginning of the application lifetime, but instead of using the product entities, clones are being made when assigning the products to the orders. This would solve the memory leak problem, but cloning would need to be implemented and maintained. It is possible that it would not be too hard rewriting the STE .tt scripts to support cloning. There would still be the problem with multiple entities in the entity context sharing the same key though.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文