具有存储库模式的实体框架 DAL、BLL

Posted

技术标签:

【中文标题】具有存储库模式的实体框架 DAL、BLL【英文标题】:Entity Framework DAL, BLL with Repository Pattern 【发布时间】:2012-09-02 05:52:00 【问题描述】:

我正在尝试使用 UI、BLL 和 DAL 构建三层架构。我正在使用带有存储库模式的实体框架。

我的问题是:实体框架生成的实体是否应该充当我的 BLL 的一部分,还是这些只是 DAL 对象?

询问的原因是因为感觉就像我在复制代码。例如:我有一个由实体框架直接从我的数据库生成的 DAL.CatEntity。这一切都很好,花花公子。然后我使用我的存储库(它是我的 DAL 的一部分)将数据提取到 DAL.CatEntity 中。然后我在我的 BLL 中使用这个 DAL.CatEntity,提取它的所有数据,并将其转换为 BLL.Cat。然后我在我的 UI 层中使用这个 BLL.Cat。

下面是一些超级简化的代码。

BLL

public Cat GetCat(string catName)
    CatEntityRepository _repository = new CatEntityRepository;
    Cat cat = null;
    CatEntity catEntity = _repository.GetSingleCat();
    cat = ConvertToCat(catEntity);
    return cat;


private Cat ConvertToCat(CatEntity entity)
    return new Cat()
        Name = entity.Name,
        Color = entity.Color,
        //....
    

用户界面:

public ActionResult method()
    Cat cat = BLL.GetCat();
    //......

似乎没有必要同时拥有 Cat 和 CatEntity。我可以只使用我的 EntityFramework 实体作为我的 BLL 的一部分,而将存储库用作我的 DLL 吗?

谢谢。

【问题讨论】:

您最好使用 AutoMapper 之类的东西,而不是创建自己的自定义映射类。所涉及的工作量要少得多。 【参考方案1】:

最终,无论您做什么,都取决于您自己。大多数应用都介于理想和糟糕之间,处于务实和实用之间。

您需要做的是查看应用的复杂性。它越复杂,它就越能从高度分离中受益。通常,应用程序的简单性并不能证明创建清晰图层所需的大量工作是合理的。

话虽如此,在我看来,在大量中小型复杂应用程序中,您可以有效地将您的实体视为业务对象。特别是,如果您将实体 POCO 和业务层的一部分,然后在您的 EF DAL 中使用这些实体,它会非常有效。

不过,我始终会提醒您,将业务或数据对象直接发送到 UI。您应该拥有在业务和 UI 之间转换的专用 UI​​ 对象。

我认为,当您可能会更改数据访问方法时,将业务与数据保持高度分离是最有意义的。例如,如果您认为可以更改为 Web 服务来获取数据,而不是直接使用 EF。此外,强大的关注点分离对单元测试有很大帮助。

【讨论】:

好点。我的应用程序将包含一个网站以及一个单独的 Web 服务。这两个都需要访问相同的 BLL。此外,更改为使用 Web 服务来访问我的数据是将来很可能发生的事情。听起来这种轻微的代码重复可能会在未来得到很好的回报。 @Kiwi:从存储库返回 ef 实体并将它们转换到外部是最糟糕的方法之一。如果要转换,请在存储库中进行并公开转换后的对象。请参阅 Mark Seemann 的 .NET 中的依赖注入一书。【参考方案2】:

如果您觉得自己在重复代码,那么您可能不需要服务层,并且您的 EF 实体可以充当业务模型。不需要业务层的简单 CRUD 应用程序通常就是这种情况。

【讨论】:

【参考方案3】:

另一种方法不是在两种类型的对象之间进行转换,而是从您的域实体创建接口并根据接口对您的存储库进行编码。

这样你可以同时烤两个蛋糕。您没有将数据层实体转换为 bll 实体,而且您仍然没有弄乱层(从某种意义上说,您的存储库不适用于具体的数据层类型)。

这种方法非常有用,但很少被描述。

【讨论】:

我实际上使用通用存储库接口来访问我的所有数据。 (我简化了上面的代码。)这就是你在说的吗?如果是这样,我仍然没有看到我不需要转换。 没有。我谈论的是实体上的接口。对于 Cat 实体,创建 ICat 接口并针对这些域接口对存储库进行编码。这样就没有转换,因为您的 EF 类将实现这些域接口。如果将来某天您更改存储库的实现,您将使您的新域类实现相同的域接口。此外,使用内存存储库和实现相同接口的辅助域类很容易在内存存储库中实现。而且,仍然不需要转换。 无转换意味着你的代码更干净、更快。而且您仍然保留不针对具体类进行编码的好处。不同之处在于,通过您的方法,您可以针对 bll 实体编写 bll 层。在我的方法中,您针对接口进行编码。 @WiktorZychla - 您的方法的问题在于它使您的数据层依赖于您的业务层,而不是相反。这不一定是问题,但需要注意。 @MystereMan:你能详细说明一下吗?为什么你认为存在依赖?我没有看到一个。领域接口定义在领域层,一层在数据层之下,二层在bll层之下。数据层根本不知道 bll 层。

以上是关于具有存储库模式的实体框架 DAL、BLL的主要内容,如果未能解决你的问题,请参考以下文章

存储库模式:DAL 或 BLL [关闭]

DAL 中的实体框架存储库模式,如何实现更新功能?

ASP.NET MVC:BLL 和 DAL 到存储库设计

设计 DAL 和 BLL - 相关表的单个/多个数据存储库

DAL 存储库模式使用 dapper 连接

具有实体框架 4.1 和父/子关系的存储库模式