EF4 DAL 设计和 ObjectContext:与同事的争论

发布于 2024-09-25 19:00:46 字数 1447 浏览 1 评论 0原文

我与一位高级开发人员一起工作,他是 .NET 架构师。在过去的 6 个多月里,我们提出了许多建设性的论点,但总的来说,我承认我们在大多数讨论中都失败了。我从和他一起工作中学到了很多东西。然而,我们目前对一个设计问题存在分歧,我想要一些意见/建议,因为他还没有设法让我相信他的立场,我会坚持我的立场,直到有人能给我证据证明我我错了。

我们使用实体框架 4.0,并在不同的模型中使用持久性感知和自我跟踪实体。我们开始使用自跟踪实体来跟踪实体图的更改,这些实体图是通过 WCF 线路序列化/反序列化到 Silverlight 应用程序的。它的效果非常好。我们还开始将自我跟踪实体用于我们未在 WCF 中采用的模型,但许多仍然是持久感知实体/模型。

我的同事认为实体框架 ObjectContext 的保留时间应尽可能短。他坚持认为它应该只存在于执行查询所需的时间长度和持久保存某些内容所需的时间长度。任何与实体一起完成的业务工作都应该独立完成。对于我们拥有的每个实体模型,我们都有一个查询类和一个持久化类,它们都是 IDisposable,并且在实例范围内具有 ObjectContext,并且在方法中具有查询/持久化逻辑。我们在业务逻辑中使用这些查询/持久性类,而不是直接在业务逻辑中使用 ObjectContext。当这些类实例被构造时,ObjectContext 也被构造;当这些类实例被释放时,ObjectContext 也被释放。这些类就像 LINQ 操作的包装器,将 EF 与业务逻辑分开并协助 LINQ 查询重用。

现在首先考虑非自跟踪实体:

我理解他为什么想要这个以及不希望有一个长期运行的 ObjectContext,但我的问题是他总是希望即使是微不足道的业务逻辑也能与 ObjectContext 分离,而事实上我们有在我们的设计下,单独的查询和持久化上下文意味着我们的业务逻辑中没有使用实体的 ObjectContext 状态跟踪。对于非自我跟踪实体,这意味着如果我们修改业务逻辑中的实体,我们还必须在持久化之前手动设置实体的修改状态。当持久保存具有多个更改的复杂图表时,这是一个真正的痛苦。我也怀疑我们是否可以像 EF 自动那样手动完成。

对于我们的自跟踪实体,这种情况是相同的,因为跟踪仅在图形被反序列化时打开,因此当在执行查询的服务内工作时,与上下文分离,自跟踪实体仍然没有跟踪。

我的问题是,实体框架使用的最佳实践是什么以及实体框架 DAL 应该如何设计? ObjectContext 应该存在多长时间?业务逻辑是否应该始终脱离 ObjectContext 来完成?如果是这样,当我们脱离 ObjectContext 工作时如何进行状态跟踪?我正在考虑的一种选择是将我们所有的实体转换为自我跟踪实体,并使用一些图形遍历代码来遍历查询的图形并打开图形中所有实体的跟踪,以便即使在服务端工作时也会打开自我跟踪(基本上模仿自跟踪实体图反序列化时发生的情况)...

我并不是建议我们长时间保留 ObjectContext,而是在查询和持久性之间分离工作,并失去 ObjectContext 的好处状态跟踪对我来说似乎很愚蠢...我们正在失去 EntityFramework 的巨大好处之一...

抱歉发了这么长的帖子...感谢任何帮助。

I work with a senior developer who is a guru .NET architect. We have had many constructive arguments over the last 6+ months and generally I concede defeat in most of our discussions. I have learned stacks from working with him. There is one design problem we are currently in disagreement with, however, and I would like some opinions/suggestions because he hasn't managed to convince me of his position, and I will stick to my guns until someone can give me evidence that I am wrong.

We use Entity Framework 4.0 and we use BOTH persistence aware AND Self Tracked Entities in different models. We started using Self Tracked Entities for tracking changes to Entity Graphs that we serialised/deserialised over the WCF wire to our Silverlight application. It works fantastically. We have also started using Self Tracked Entities for models that we are NOT taking across WCF, but many remain as persistent aware Entities/Models.

My co-worker believes that Entity Frameworks ObjectContext should be kept around for the shortest time possible. He insists that it should only be around for the length of time needed to do a query and the length of time needed to persist something. Any business work done with Entities should be done detached. For each Entity Model we have, we have a query class and a persistent class that are both IDisposable and have the ObjectContext at instance scope and have the query/persistence logic in methods. We use these query/persistence classes in our business logic rather than using the the ObjectContext directly in business logic. When these class instances are constructed so is the ObjectContext and when Disposed, so is the ObjectContext Disposed. These classes are like wrappers around our LINQ operations separating EF from the business logic and assisting with LINQ query re-use.

Now first consider non-Self Tracked Entities:

I understand why he wants this and the desire to not have a long running ObjectContext, but my problem is that he always wants even trivial business logic to be detached from the ObjectContext and the fact that we have a separate query and persistence context under our design means that there is no ObjectContext state tracking of Entities being used in our business logic. For non-Self Tracked Entities this means that if we modify Entities in our business logic we must also set the Modified state of the entities manually prior to persisting. This is a REAL pain when persisting complex graphs with multiple changes. Also I doubt we can do it manually as well as EF does it automatically.

For our Self Tracked Entities this situation is the same because tracking is only turned on when graphs are de-serialised and so when working WITHIN a service where the query was performed, detached from the Context, there is still no tracking with Self-Tracked Entities.

My question is, what is the best practice for Entity Framework use and how should an Entity Framework DAL be designed? How long should the ObjectContext be around? Should business logic always be done detached from the ObjectContext? If so how do we do state tracking when working detached from the ObjectContext? One option I am thinking about is converting ALL of our entities to Self-Tracked Entities and using some graph traversal code to traverse queried graphs and turn tracking on for all of the Entities in the graph so Self Tracking is turned on even when working service side (basically mimicking what happens when the Self-Tracked Entities graph is de-serialised)...

I am not proposing that we keep the ObjectContext around for long periods of time, but working detached between query and persistence and losing the benefits of the ObjectContext state tracking to me seems silly...we are losing one of the great benefits of EntityFramework...

Sorry for long post...any help appreciated.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不知所踪 2024-10-02 19:00:46

Microsoft 建议 ObjectContext 的生命周期应较短,而我的经验使我相信 ObjectContext 的生命周期在理想情况下应与 Web 请求/用户操作的持续时间相关。

我犯了一个错误,试图在桌面应用程序中使用全局的、长期存在的 ObjectContext,这完全是一场灾难。如果您要实现缓存、欠下/重做编辑语义等功能,那么您应该考虑使用与底层数据实体明显分离的 ViewModel 类的设计。使用 EntityFramework 帮助您构建模型对象图,然后从中构建 ViewModel。当您想要保存更改时,允许您的 ViewModel 存储库重新连接到底层实体,更改其属性并保存更改。这允许更“可缓存”、灵活、独立于 ORM、单元测试友好的设计。

在更改跟踪方面,请不要将其视为一种廉价的“用户进行更改”的 UI 机制,而应将其视为一种昂贵的机制,用于跟踪在保存更改时需要考虑哪些最近创建的实体。

Microsoft recommends that the ObjectContext be short lived, and my experience has led me to believe that the life-span of an ObjectContext should ideally correlate to the duration of a web-request / user operation.

I made the mistake of trying to use a global, long-lived ObjectContext in a desktop application, and it was a total disaster. If you're going to implement things like caching, under/redo edit semantics, etc. then you should consider a design that uses ViewModel classes which are distinctly seperate from the underlying data entities. Use the EntityFramework to help you construct your Model object graph, then build the ViewModel from that. When you want to save changes, allow your ViewModel Repository to reconnect to the underlying entities, alter their properties and save changes. This allows for a more "cachable", flexible, ORM independant, unit-test-friendly design.

In terms of change tracking, try not to think of it as a cheap "user-made-a-change" mechanism for the UI, but rather as an expensive mechanism for tracking which recently-created entities need to be considered when saving changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文