从架构上讲,诸如Microsoft的Entity Framework之类的数据库抽象层是否使对单独的数据访问层的需求无效?


11

原来的样子

多年以来,我一直在组织软件解决方案,例如:

  • 数据访问层(DAL),用于抽象访问数据的业务
  • 业务逻辑层(BLL),用于将业务规则应用于数据集,处理身份验证等。
  • 实用程序(Util)只是我逐渐建立的常用实用程序方法的库。
  • 表示层当然可以是Web,桌面,移动等。

现在的样子

在过去的四年左右的时间里,我一直在使用Microsoft的Entity Framework(我主要是.NET开发人员),并且由于Entity Framework已经完成了DAL工作,因此我发现拥有DAL变得越来越麻烦。我的DAL曾经做过的工作:它抽象了针对数据库运行CRUD的业务。

因此,我通常以一个DAL结束,该DAL具有如下方法的集合:

public static IQueryable<SomeObject> GetObjects(){
    var db = new myDatabaseContext();
    return db.SomeObjectTable;
}

然后,在BLL中,该方法将按如下方式使用:

public static List<SomeObject> GetMyObjects(int myId){
    return DAL.GetObjects.Where(ob => op.accountId == myId).ToList();
}

当然,这是一个简单的示例,因为BLL通常会应用多行逻辑,但是在这样有限的范围内维护DAL似乎有点多余。

放弃DAL并像这样简单地编写我的BLL方法会不会更好:

public static List<SomeObject> GetMyObjects(int myId){
    var db = new myDatabaseContext();
    return db.SomeObjectTable.Where(ob => op.accountId == myId).ToList();
}

由于上述原因,我正在考虑从未来的项目中删除DAL,但在这样做之前,我想在这里进行社区民意调查,以了解您的事后见解/见解/意见,然后再执行项目并发现我没有遇到的问题。没想到。

任何想法表示赞赏。

更新资料

共识似乎是不需要单独的DAL,但是(在此处做出我自己的推断)是避免供应商锁定的好主意。例如,如果我有一个DAL,它如上所述提取了EF调用,切换到其他供应商后,我不需要重写BLL。只有DAL中的那些基本查询才需要重写。话虽如此,我发现很难想象会发生这种情况。我已经可以建立一个Oracle数据库的EF模型,并且已经提供了MSSQL,我非常确定MySql也可以(??),因此我不确定额外的代码是否会带来可观的投资回报。


3
您的数据访问层与EF有何不同?EF不是数据访问层吗?只有我可以看到,以保持自己的抽象的业务逻辑和EF之间的原因是使磕碰容易测试,避免厂商锁定英寸
马里安Venema

2
这就是我的观点-我的观点没有区别,但我正在寻找对策。谢谢。
马特·卡察特

3
我个人认为没有理由创建单独的DAL,因为EF / NHibernate本身就是数据访问层。正如Marjan提到的那样,如果使用EF 可以看到数据库供应商发生了变化,可以考虑使用它,在NHibernate中,您可以在一行代码中交换驱动程序(甚至用于内存中测试的SQLite驱动程序),因此(IMO)不必要的代码。
PatrykĆwiek13年

3
无需两个DAL。正如其他人所述,请保留您的BLL,但要小心避免将BLL锁定在特定于供应商的结构中。我总是喜欢看到事物降到字符串或整数级别。然后,我知道我可以轻松地通过非常原始的通道(例如Web服务,串行端口,电报链接)公开整个BLL / DAL连接,只是在开玩笑。
安迪斯·史密斯

1
重新更新:这一额外的层可以使busineslayer的单元测试变得更加容易,因为对的模拟/存根/伪造GetMyObjects(int myId)比对的模拟/存根/伪造更容易GetObjects.Where(ob => op.accountId == myId).ToList()
2013年

Answers:


6

不知道这是否是您要寻找的答案。

我们这样做是为了使事情分开/井井有条。是的,EF / NHibernate是数据访问。.但是我们通过通用存储库设置将它的使用限制为自己的程序集。该程序集还包含我们所有的NHibernate映射,Session工厂,用于处理多个数据库的代码等。

我们仍然将其称为“数据访问层”,因为存在整个程序集来支持我们的ORM。

我可能应该注意,我们的主应用程序引用了5个数据库,大约有4-500个域对象/映射和各种模式。因此,此设置对我们有意义。也许对于较小的应用程序,您可以跳过此程序集,但是..我非常喜欢有组织的代码,并且无论如何都会这样做:)


2

我将EF和DAL视为企业系统中的独立组件。数据访问层是其他服务用来执行数据持久性和管理的抽象。通常,实体框架围绕查询,更新,删除和插入构建一个不错的API,但是在核心方面,它们仍然需要直接连接到后端数据源。因此,任何类型的路由或防火墙都将阻止EF正常工作,从而需要您创建EF中介组件。

这是一个高级示例,显示了DAL和EF适合的位置:

-------------    -------                                    ----------------    ------
| Service A | -> | DAL | -> { LOCAL / LAN / WAN ACCESS } -> | DAL BACK-END | -> | EF |
-------------    -------                                    ----------------    ------

根据我的经验,更好的设计是永远不允许业务逻辑或服务实现直接访问EF层。取而代之的是提供一种用于处理所有持久性数据的抽象,使您可以通过网络传送请求或在本地执行请求。

这种设计虽然引入了一些泄漏的抽象。因此,应根据具体情况进行考虑。

一些问题要问:

  • 所有访问您的数据的组件都能够获得到后端数据存储的连接吗?
  • 您的EF是否允许您跨不同类型的数据存储聚合数据集?例如,将SQL数据库与MongoDB一起使用以获取文档。

1

如今,是否要更改数据存储的问题比以前更加有趣,因为问题可能不仅是您是否要在MS SQL或Oracle SQL之间进行交换,而是更大的问题,即您是否可能会使用各种NoSQL数据存储产品中的一种作为您的数据存储库。

如果很有可能发生这种更改,那么将EF代码隔离在DAL中可能很有价值,以便将来可以引入一个新的DAL,以将存储库请求映射到NoSQL数据库。无论如何,由于与数据库相关的假设当然会逐渐蔓延,所以这样的更改最终可能会彻底重写BLL。

同样,DAL中的EF可能会使BLL代码单元测试的数据访问模拟更为简单。

因此,我认为EF(或其他ORMS)并不一定会使对数据访问层的需求消失。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.