2

I've got two entities in the entity framework. Now I want to seperate them by putting an Interface of the DAL entity into the Domain.

So the end result would be:

DAL

  • Person : IPerson (EF Entity)
  • Book : IBook (EF Entity)

Domain

  • Interfaces (Folder)
    • IPerson
    • IBook
  • Person (Domain entity)
  • Book (Domain entity)

Now the problem is, should my Dal.Person have a virtual Book or IBook? How should both the DAL.Person, IPerson and Domain.Person look like (give me just really small example for the interfacing)

4
  • I don't think the DAL should implement the Domain interface. Commented Mar 12, 2012 at 11:08
  • @Jodrell dotnetslackers.com/articles/aspnet/… says you should to remove the dependencies to EF /L2SQL Commented Mar 12, 2012 at 11:33
  • Is the Domain the BLL or the Model? Commented Mar 12, 2012 at 11:37
  • @Jodrell sorry I'll revise my post. I mean DAL and Domain, I need a way to remove dependencies between those two. Commented Mar 12, 2012 at 11:43

4 Answers 4

1

EF doesn't support working with interfaces so you cannot have public virtual IBook ... in your Person entity if you want to use it as navigation property handled by EF.

Sign up to request clarification or add additional context in comments.

1 Comment

Then what is the right way of removing the dependency between entity framework and the domain classes?
1

The answer to your question entirely depends on your objective here.

If you are creating domain level Interfaces with the rationale that you might (at some stage later) swap over the DAL from Entity Framework to something entirely different (such as a 3rd party web-service, or perhaps xml serialisation) - then you will be aiming to completely seperate any concrete logic between the Domain and the DAL.

Where possible, you want your Domain to operate on the Domain entites/interfaces and your DAL to operate on DAL entities/interfaces, whilst implementing the interfaces specified in your Data Access

Therefore, your DAL object DAL.Person should contain a Book object, and implement from the IPerson interface at a domain level.

I'll give some examples as requested:

#region Domain Objects


    public interface IPerson
    {
        List<IBook> Books { get; private set; }
    }

    public interface IBook
    {
        string Name { get; private set; }
    }

    #endregion

    #region DAL/Entity Framework Auto Generated classes

    public class Person : IPerson
    {
        public List<Book> Books {get; private set;}
    }

    public class Book : IBook
    {
        public string Name { get; private set; }
    }

  #endregion

Contrary to Jodrells comment, I think that if there was a requirement to 'Hot-Swap' the Data Access Layer there could be a case for the DataAccess layer implementing the interface contracts described in the Domain layer.

To be honest though, it is rare that I have seen this requirement - and usually you are best off extending the auto-generated Entity Framework classes (through partial) and passing around the application, removing the duplication that would be required by specifying the domain objects and contracts themselves. So in essence, your Entity-Framework classes becomes your Domain layer.

And I should mention that you should use POCO classes as per comments above

3 Comments

In my niavety I had assumed this was the case
@Patrick McCurley Thanks for your really nice comment! Although having the entity framework classes become my domain layer is the problem for me. This customer wants to have a quick implementation with Entity Framework first for quick development. But later on he wants to swap the whole EF with just plain SQL so it'll be quicker. On the sidenote, Ladislav (other comment) says it isn't possible to use interfaces in EF.
But this code doesn't compile. Person does not implement correctly List<IBook> Books
1

I've not seen Interfaces used to decouple EF. I know they are used for decoupling with dependency injection, but perhaps there is too much going on with EF behind the scenes for this to work (dynamic proxies, change detection).

I'd suggest implementing a Repository layer.

Step 1

Start with the simplest pattern - model (Person and Book) in a domain and EF in a DAL layer, using the standard EF procedure for code first. EF implements repository features in the DbSet<Person> and DbSet<Book> (but of course this type of repository is locked into EF).

Make a deliverable app work with this pattern, you can demo functionality quite quickly. This allows you to focus on app logic and not worry too much about persistence.

Step 2

Put a repository class or classes between domain and DAL. Replace the domain calls to DbSet<Person> and DbSet<Book> with calls to IQueryable<Person> and IQueryable<Book> in the repository. The repository collections initially just point at the EF DbSet<> collections.

Implement Save() in the repository as well. Initially, it just calls DbContext.SaveChanges().

Check the functionality stays the same.

Step 3

Replace the source of the repository IQueryable<>'s with whatever is equivalent in your new DAL. This may or may not be tricky, depending on the shape of the new DAL.

I followed this kind of process - started with an XML serialized DAL, moved it to EF, refactored one table back to a local XML file, and next step will be to refactor another table to a web service on an ESB.

BTW, you mention replacing EF with SQL for performance. We found EF slow for bulk inserts, because of the row-by-row style it uses.

To get around this, I implemented SqlBulkCopy within the EF based repository (instead of wholesale replacement of EF which has other features we really liked). It's quick, but takes a while to piece together.

Comments

0

I've been having this problem for AGES.

In the past I have used DTOs with AutoMapper, but this never seemed very elegant, but I think I've found a slightly neater way - have a look and see if it suites your design.

Basically you expose TWO links in your - in your concrete class - one implemetents the Ibook Book and one that implements Book BookNavigation

the first one implements the interface requirements (Ibook) and the second implements a concrete class to make EF Happy. You then bind the two to the SAME underlying private Book book.

I explain it in more detail here:

http://bretthargreaves.wordpress.com/2014/11/11/entity-framework-and-interface-issues/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.