在基于 WCF 的企业应用程序中使用实体框架的哪种变体
我们正在设计一个包含大约 100 个表和复杂业务逻辑的应用程序。 Windows 窗体将在客户端使用,WCF 服务将在服务器上使用 MSSQL。
自定义 DTO 用于客户端-服务器通信,业务实体不是分布式的。
使用实体框架的哪种变体(以及原因):
- EF 4.0 EntityObjects
- EF 4.0 POCO
- EF 4.1 DbContext
- 其他要求
数据库优先方法是必需的。
另外,是否值得实施存储库模式?这似乎有点多余,因为映射本身有一个抽象级别,而 DTO 的使用则有另一个抽象级别。我目前倾向于为每个返回 IQueryable 的实体使用自动生成的可扩展存储库,只是为了有一个地方放置常见查询,但仍然允许直接从服务层查询实体模型。
We are in a process of designing an application with approx 100 tables and complicated business logic. Windows Forms will be used on the client side and WCF services with MSSQL on the server.
Custom DTOs are used for client-server communication, business entities are not distributed.
Which variant of Entity Framework to use (and why):
- EF 4.0 EntityObjects
- EF 4.0 POCO
- EF 4.1 DbContext
- Something else
Database-first approach is a requirement.
Also, is it worth implementing a Repository pattern? It seems a bit redundant, as there is one level of abstraction in the mapping itself and another one in the use of DTOs. I'm currently leaned towards using auto-generated extendable repositories for each entity returning IQueryable, just to have a place to put common queries, but still allowing querying entity model directly from the Service Layer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用哪个变体?基本上,一旦您拥有自定义 DTO,唯一的问题是您是否想要控制实体代码(它们的基类)并使它们独立于 EF?您想先使用代码吗?如果所有问题的答案都是“否”,那么您可以使用 EntityObjects。如果你想让实体持久化或使用自定义基类,你应该去 POCO。如果您想首先使用代码或新的 DbContext API,您将需要 EF 4.1。一些相关主题:
还有更多东西设计服务层时要考虑。您应该了解在 WCF 中使用 EF 时必须处理的复杂情况。您的服务将向 WinForms 应用程序提供数据,并且它将在“分离模式”下与它们一起工作。一旦用户完成了他想做的所有更改,他就会将数据发布回服务。但问题来了——你必须告诉 EF 发生了什么变化。例如,如果您允许用户更改其所有订单商品的订单(更改商品数量、添加新商品、删除某些商品)您必须准确说出 EF 发生了哪些变化、添加了哪些内容以及删除了哪些内容。当您使用单个实体时,这很容易,但是一旦您允许用户更改对象图(尤其是多对多关系),那就非常困难了。最常见的解决方案是加载整个图并将来自传入 DTO 的状态合并到已加载和附加的图。其他解决方案是使用 自我跟踪实体 EntityObjects/POCO + DTO。
在讨论存储库时,我建议您参考 这个答案引用了许多其他答案,讨论存储库、它们可能的冗余以及在使用它们只是为了使代码可测试时可能出现的错误。通常,只有在真正需要该层时才应添加每个层 - 因为可以更好地分离关注点。
Which variant to use? Basically once you have custom DTO the only question is do you want to have control over entities code (their base class) and make them independent on EF? Do you want to use code first? If the answers to all questions are no then you can use EntityObjects. If you want to have entities persistence ignorant or use custom base class you should go to POCO. If you want to use code first or new DbContext API you will need EF 4.1. Some related topics:
There are more things to consider when designing service layer. You should be aware of complications you will have to deal with when using EF in WCF. Your service will provide data to WinForms application and it will work with them in "detached mode". Once user will do all changes he wants to do he will post data back to the service. But here comes the problem - you must tell EF what has changed. If you for example allow user to change order with all its order items (change quantity in items, add new items, delete some items) you must say EF exactly what has changed, what was added and what was deleted. That is easy when you work with single entity but once you allow user to change object graph (especially many-to-many relations) then it is quite tough. The most common solution is loading the whole graph and merge the state from incoming DTOs to loaded and attached graph. Other solution is using Self tracking entities instead of EntityObjects/POCOs + DTOs.
When discussing repositories I would refer you to this answer which refers many other answers discussing repositories, their possible redundancy and possible mistakes when using them just to make your code testable. Generally each layer should be added only if there is real need for the layer - due to better separation of concerns.
POCO 的主要优点是这些类可以成为您的 DTO,因此如果您已经拥有正在使用的自定义 DTO,POCO 似乎有点多余。但是,还有一些其他优点可能对您有价值,也可能没有价值,因为您没有提到单元测试作为要求。如果您打算编写单元测试,那么 POCO 仍然是最佳选择。您可能不会注意到 4.0 POCO 和 4.1 之间有太大区别,因为您不会使用代码优先功能(免责声明:我只使用过 4.0 POCO,所以我不太熟悉任何细微的差异两者之间,但它们似乎或多或少是相同的——基本上我已经在 4.0 中使用 POCO 并且没有看到任何让我想要更新所有内容以使用的东西4.1)。
此外,根据您是否计划对该层进行单元测试,在使用实体框架时实现存储库/工作单元模式仍然有价值。它用于抽象数据访问逻辑(上下文),而不是实体本身,并允许您执行诸如在单元测试中模拟上下文之类的操作。我所做的是复制上下文的 T4 模板并使用它来创建接口,然后编辑上下文的 T4 模板并让它实现该接口并使用
IObjectSet
而不是ObjectSet
。 的是因此,我最终得到
:所以
我想这实际上取决于您是否计划为此层编写单元测试。如果您不会做任何需要模拟上下文进行测试的事情,那么最容易使用的可能是 4.0 EntityObjects,因为您不打算在层之间传递实体,并且需要最少的努力实施。如果您计划使用模拟,那么您可能需要使用 POCO 并实现存储库/工作单元。
The main advantage of POCOs is that those classes can be your DTOs, so if you've already got custom DTOs that you're using, POCO seems a bit redundant. However, there are some other advantages which may or may not have value to you, since you didn't mention unit testing as a requirement. If you plan to write unit tests, then POCO is still the way to go. You probably won't notice much difference between 4.0 POCO and 4.1 since you won't be using the code-first feature (disclaimer: I've only used 4.0 POCO, so I'm not intimately familiar with any minor differences between the two, but they seem to be more or less the same--basically I was already using POCO in 4.0 and haven't seen anything that's made me want to update everything to use 4.1).
Also, depending on whether you plan to unit-test this layer, there's still value in implementing the repository/unit of work patterns when using Entity Framework. It serves to abstract away the data access logic (the context), not the entities themselves, and allows you to do things like mocking your context in unit tests. What I do is copy the T4 template for my context and use it to create the interface, then edit the T4 template for the context and have it implement that interface and use
IObjectSet<T>
instead ofObjectSet<T>
. So instead of:I end up with:
and
So I guess it really comes down to whether or not you plan to write unit tests for this layer. If you won't be doing anything that would require mocking out your context for testing, then the easiest thing to use would probably be 4.0 EntityObjects, since you aren't planning to pass your entities between layers and it would require the least effort to implement. If you plan to use mocking, then you'll probably want to use POCO and implement repository/unit of work.