11

The way it was

For years, I have organized my software solutions as such:

  • Data Access Layer (DAL) to abstract the business of accessing data
  • Business Logic Layer (BLL) to apply business rules to data sets, handle authentication, etc.
  • Utilities (Util) which is just a library of common utility methods I have built over time.
  • Presentation Layer which could of course be web, desktop, mobile, whatever.

The way it is now

For the past four years or so I have been using Microsoft's Entity Framework (I am predominately a .NET dev) and I am finding that having the DAL is becoming more cumbersome than clean on account of the fact that the Entity Framework has already done the job that my DAL used to do: it abstracts the business of running CRUDs against a database.

So, I typically end up with a DAL that has a collection of methods like this one:

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

Then, in the BLL, this method is used as such:

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

This is a simple example of course as the BLL would typically have several more lines of logic applied, but it just seems a bit excessive to maintain a DAL for such a limited scope.

Wouldn't it be better to just abandon the DAL and simply write my BLL methods as such:

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

I am considering dropping the DAL from future projects for the reasons stated above but, before doing so, I wanted to poll the community here for your hindsight/foresight/opinions before I get down the road on a project and discover a problem I didn't anticipate.

Any thoughts are appreciated.

Update

The consensus seems to be that a separate DAL isn't necessary but (making my own inference here) is a good idea to avoid vendor lock in. For example, if I have a DAL that is abstracting EF calls as illustrated above, if I ever switch to some other vendor I don't need to rewrite my BLL. Only those basic queries in the DAL would need to be rewritten. Having said that, I am finding it tough to envision a scenario in which this would happen. I can already make an EF model of an Oracle db, MSSQL is a given, I am pretty sure that MySql is possible as well (??) so I am not sure if the extra code would ever grant a worthwhile ROI.

Matt Cashatt
  • 3,315
  • 5
  • 24
  • 35
  • 3
    How is a/your data access layer different from EF? Isn't EF a data access layer? Only reasons I can see to keep your own abstraction in between your business logic and EF is to make stubbing easier for testing and to avoid vendor lock in. – Marjan Venema Aug 23 '13 at 13:30
  • 2
    That's my point--there is no difference in my view, but I am looking for counter points. Thanks. – Matt Cashatt Aug 23 '13 at 13:33
  • 3
    Personally I see no reason to create a separate DAL, because EF/NHibernate are data access layers in themselves. As Marjan mentioned, with EF you can consider it *if* you can see database vendor changing, in NHibernate you can swap drivers in one line of code (even SQLite driver for in-memory testing), so it would be (IMO) unnecessary code. – Patryk Ćwiek Aug 23 '13 at 13:35
  • 3
    No need to have two DALs. As others have stated, keep your BLL, but be careful to avoid locking your BLL into vendor specific constructs. I always like to see things get down to the string or integer level. Then I know that I could easily expose the whole BLL / DAL junction across a very primitive channel like web services, serial port, telegraph link, just kidding. – Andyz Smith Aug 23 '13 at 13:40
  • 1
    re Update: this extra layer can make Unittests of the busineslayer much easier because mocking/stubbing/faking of `GetMyObjects(int myId)` is easier than mocking/stubbing/faking of `GetObjects.Where(ob => op.accountId == myId).ToList()`. – k3b Sep 04 '13 at 13:53

3 Answers3

6

Not sure if this is the answer you're looking for.. but here goes.

We do it to keep things separated/organised. Yes, EF/NHibernate are data access.. but we limit its use to its own assembly with a generic repository setup. This assembly also contains all of our NHibernate mappings, Session factory, code for handling multiple databases, etc.

We still refer to it as the "Data Access Layer", because the entire assembly exists to support our ORM.

I should probably note that our main app references 5 databases, has roughly 4-500 domain objects/mappings and various schemas. So, this setup makes sense for us. Perhaps for a smaller app you would skip this assembly but.. I am a sucker for organised code and would probably do it anyway :)

Simon Whitehead
  • 474
  • 3
  • 9
2

I view the EF and DAL as separate components in an Enterprise system. The Data Access Layer is an abstraction that other services use to perform data persistence and management. Typically Entity Frameworks build a nice API around querying, updating, deleting and inserting however at the core they still require a direct connection to the back-end data source. So any type of routing or firewalls will stop the EF from working, thus requiring you to create a EF mediation component.

Here is a high-level example showing where DAL and EF fit in:

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

It has been my experience that a better design is to never allow the business logic or service implementations direct access to the EF layer. Instead, to provide an abstraction for working with all the persistent data which allows you to ship requests over the wire or perform them locally.

This design introduces some leaky abstractions though. So it should be considered on a case by case basis.

Some questions to ask:

  • Will all the components accessing your data be able to obtain a Connection to the back-end data store?
  • Does your EF allow you to aggregate data sets across different types of data stores? For example using a SQL database with MongoDB for documents.
Andrew T Finnell
  • 3,112
  • 17
  • 18
1

Nowadays the question of whether or not you are going to change data storage is more interesting than it used to be, since the question might not be just whether or not you would swap between MS SQL or Oracle SQL, but the bigger question of whether you might use on of the various NoSQL data storage offerings as your data repository.

If there was a serious possibility of that kind of change it might be valuable to keep your EF code isolated within your DAL so that you could introduce a new DAL in the future which mapped your repository requests to a NoSQL database. It might be that such a change would end up with a wholesale rewrite of your BLL anyway because of db related assumptions which creep in of course.

Similarly, EF within a DAL would probably make mocking of data access for your BLL code unit tests more straightforward.

So my view is that EF (or other ORMS) does not necessarily void the need for a data access layer.

Alex White
  • 141
  • 2