1

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

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

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

  1. 通过部分类扩展同一项目内的实体类
  2. 使用接口(由实体类和相关的 BLL 类实现)。前者在程序员中更受欢迎。

上述解决方案的缺点:

  1. 我们需要在同一个项目中添加代码作为部分类的一部分。这适用于添加属性和方法,但不适用于覆盖某些内容(即,在业务逻辑层设置属性之前添加验证)
  2. 如果实体模型发生更改,我们需要再次手动从实体类中提取接口,并且还需要对 BLL 相关类进行另一次更改(两次手动解决)。

我的问题是为什么我们根本不从相关实体类继承我们的 BLL 类并扩展/覆盖它们的方法和属性?

4

1 回答 1

4

您需要记住的一件事是,像实体框架这样的 ORM 实际上并没有创建简单的数据访问层(当通过一般的 3 层架构查看时)。它们为您提供的更多的是一个业务层,对数据访问交互具有更精细的控制级别。我认为可以说 EF 本质上成为您的 DAL,而上下文和实体类型可以是 BLL。

当通过更多的 MVC 或 MVVM 架构查看时,这条线更容易看到,其中您有一个模型(您的 EF 层)、一个控制器或视图模型(业务逻辑所在的位置,它封装了模型)和一个视图。

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

例如,如果您的实体类型有一个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# 编译器会从代码中完全删除该函数以及对它的所有调用,就好像它从一开始就从未存在过一样。这使得类型更小并且对其他属性的调用更快,因为它不必为调用空函数而烦恼。

于 2011-02-10T21:55:29.577 回答