继承实体类并扩展该类
我使用 Entity Framework 4.0 创建数据访问层。然后我发现我的业务逻辑层具有与 DAL 相同的对象,但具有一些扩展(即更多属性、一些函数以及 setter 处的数据验证...)。
我计划将 DAL 和 BLL 放在不同的项目中,并正在寻找在 BLL 中使用实体类并防止代码冗余的最佳实践。
当我搜索时,有两个主要想法:
- 通过部分类使用接口扩展同一项目内的实体类
- (由实体类和相关的 BLL 类实现)。前者更受程序员欢迎。
上述解决方案的缺点:
- 我们需要在同一项目中添加代码作为分部类的一部分。这对于添加属性和方法很有用,但不适合覆盖某些内容(即,在业务逻辑层设置属性之前添加验证)
- 如果实体模型发生更改,我们需要再次从实体类中手动提取接口,并且还需要另一个需要更改 BLL 相关类(需要两个手动解决方案)。
我的问题是为什么我们不从相关实体类继承 BLL 类并扩展/覆盖它们的方法和属性?
I used Entity Framework 4.0 for creating my Data Access Layer. Then I found that my Business Logic Layer has the same objects as DAL but with some extensions (i.e, more properties, some functions, and data validation at setters...).
I planned to have DAL and BLL in separate projects and was looking for best practice to use entity classes in BLL and prevent redundancy in code.
As I searched and there are two major ideas:
- extending entity classes inside the same project by partial classes
- Using interfaces (implemented by entity class and relevant BLL class). Former is more popular among programmers.
Disadvantages for above solutions:
- We need to add the code at the same project as part of the partial class. This is good for adding properties and methods but it's not good for overriding something (i.e, adding validations before setting a property at Business Logic Layer)
- If the entity model is changed, we need to manually extract the interfaces from entity classes again and also another change in BLL related class is needed (two manual work around).
My question is why we simply doesn't inherit our BLL classes from relevant entity classes and extend/override their methods and properties ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要记住的一件事是,像实体框架这样的 ORM 实际上并不创建简单的数据访问层(当通过一般的 3 层架构查看时)。它们为您提供的更多的是业务层,对数据访问交互进行更细粒度的控制。我认为可以说 EF 本质上成为您的 DAL,而上下文和实体类型可以是 BLL。
当通过更多的 MVC 或 MVVM 架构查看时,这条线更容易看到,其中您有一个模型(您的 EF 层)、一个控制器或视图模型(业务逻辑所在的位置,封装了模型)和一个视图。
无论如何,因为 EF 实际上必须直接实例化实体类型,所以继承不会给您带来多大好处,因为 EF 不会使用您的子类型作为返回的实体。 EF 中验证和类似任务的解决方案是同时使用部分类(您显然知道)和部分方法。 EF 中的默认代码生成模板为
OnPROPERTYNAMEChanging
和OnPROPERTYNAMEChanged
的所有标量属性生成部分方法。例如,如果您的
User
实体类型有一个int UserId
属性,您可以创建一个如下所示的分部类:当然,您可以只使用一个或其他,如果你愿意的话。分部方法相对于继承调用(假设甚至可能)的优点是分部方法是非虚拟的(因此没有虚拟表查找来调用正确的成员)并且仅被编译如果有实际的实现,则作为课程的一部分。
换句话说,即使您可以进入设计器代码并查看声明,
如果您实际上没有向函数添加方法体,那么 C# 编译器也会从代码中完全删除该函数以及对它的所有调用,如下所示如果它从一开始就不存在的话。这使得类型更小并且对其他属性的调用更快,因为它不必费心调用空函数。
One thing that you need to keep in mind is that ORM's like the Entity Framework don't actually create a simple data access layer (when viewed through the general 3-tier architecture). What they give you is much more of a business layer with a slightly more granular level of control over the data access interaction. I think it can be argued that EF essentially becomes your DAL and the context and entity types can be the BLL.
The line's a lot easier to see when viewed through more of an MVC or MVVM architecture, where you have a model (your EF layer), a controller or viewmodel (where the business logic sits, which encapsulates the model), and a view.
Anyhow, because EF actually has to instantiate the entity types directly, inheriting wouldn't do you much good because EF won't use your subtype as the returned entity. The solution for validation and similar tasks in EF is to make use of both partial classes (which you obviously know about) and partial methods. The default code-generation templates in EF produce partial methods for all scalar properties for
OnPROPERTYNAMEChanging
andOnPROPERTYNAMEChanged
.For instance, if you have an
int UserId
property on yourUser
entity type, you can create a partial class that looks like this:You can, of course, only use one or the other if you like. The advantage that partial methods would have over an inherited call (assuming it was even possible) is that partial methods are non-virtual (so there's no virtual table lookup to call the correct member) and are only compiled as part of the class if there's an actual implementation.
In other words, even though you can go into the designer code and see the declarations for
If you don't actually add a method body to the function, then the C# compiler completely removes the function and all calls to it from the code, as if it had never been there in the first place. This makes the types smaller and the calls to other properties faster, since it won't have to bother with calling an empty function.