继承实体类并扩展类

时间:2011-02-10 21:42:33

标签: entity-framework inheritance business-logic-layer

我使用Entity Framework 4.0来创建我的数据访问层。然后我发现我的业务逻辑层与DAL具有相同的对象,但有一些扩展(即更多属性,某些功能和设置者的数据验证......)。

我计划在单独的项目中使用DAL和BLL,并且正在寻找在BLL中使用实体类并防止代码冗余的最佳实践。

我搜索时有两个主要想法:

  1. 通过分组类扩展同一项目中的实体类
  2. 使用接口(由实体类和相关BLL类实现)。前者在程序员中更受欢迎。
  3. 上述解决方案的缺点:

    1. 我们需要在同一个项目中添加代码作为分部类的一部分。这对于添加属性和方法很有用,但它不适合覆盖某些东西(即在业务逻辑层设置属性之前添加验证)
    2. 如果更改了实体模型,我们需要再次从实体类中手动提取接口,并且还需要另外更改BLL相关类(两个手动解决方法)。
    3. 我的问题是为什么我们不会从相关实体类继承我们的BLL类并扩展/覆盖它们的方法和属性?

1 个答案:

答案 0 :(得分:3)

您需要记住的一件事是,ORM与实体框架一样,实际上并不创建简单的数据访问层(通过一般的3层架构查看)。他们为您提供的更多是业务层,对数据访问交互的控制程度略高。我认为可以认为EF本质上成为你的DAL,而上下文和实体类型可以是BLL。

通过更多MVC或MVVM体系结构查看该行时更容易看到,其中您有一个模型(您的EF层),一个控制器或视图模型(业务逻辑所在的位置,它封装了模型),以及一个观点。

无论如何,因为EF实际上必须直接实例化实体类型,所以继承不会对你有好处,因为EF不会将你的子类型用作返回的实体。 EF中的验证和类似任务的解决方案是使用部分(您显然知道)和部分方法。 EF中的默认代码生成模板为OnPROPERTYNAMEChangingOnPROPERTYNAMEChanged的所有标量属性生成部分方法。

例如,如果您的int UserId实体类型上有User属性,则可以创建一个如下所示的部分类:

public partial class User
{
    partial void OnUserIdChanging(int newUserId)
    {
        // do something
    }

    partial void OnUserIdChanged()
    {
        // do something
    }
}

当然,如果您愿意,您只能使用其中一种。部分方法优于继承调用(假设甚至可能)的优点是部分方法是非虚拟的(因此没有虚拟表查找来调用正确的成员)并且编译作为课程的一部分,如果有实际的实施。

换句话说,即使您可以进入设计器代码并查看

的声明
partial void OnUserIdChanging(int value);
partial void OnUserIdChanged();

如果你实际上没有为函数添加方法体,那么C#编译器会完全删除函数以及从代码中对它的所有调用,就好像它从来没有在那里一样。这使得类型更小,对其他属性的调用更快,因为它不必为调用空函数而烦恼。