1

In my ASP.NET MVC 3 application I am to use EF4.3 as an ORM framework for now. I want to have an ability to substitute it in future in case I need to. This calls for defining an interface, that will point to DbContext implementation in case of EF.

What do I define in my Interface for queryable object?

For example in my case I am going to do the following, but don't know if it's a correct way to go:

in my Interface:

    IQueryable<AnonymousUser> AnonymousUsers { get; }

    int SaveChanges();

in my DbContext:

    public DbSet<AnonymousUser> AnonymousUsers { get; set; }

    IQueryable<AnonymousUser> IThoughtCatStorage.AnonymousUsers
    {
        get { return AnonymousUsers; }
    }

As you can see, using an IQueryable is one way to abstract the DbSets out.

Is this the best way? (I know this sounds rather discussion-like, but I just want to know if currently there is a more generalizing way to define an ORM-access interface. )

Maxim V. Pavlov
  • 10,303
  • 17
  • 74
  • 174
  • 3
    It's probably not a good idea: http://stackoverflow.com/questions/1699607/asp-mvc-repository-that-reflects-iqueryable-but-not-linq-to-sql-ddd-how-to-que/1699756#1699756 – Mark Seemann Feb 16 '12 at 13:23
  • 1
    The price for the abstraction might simply be too high: http://ayende.com/blog/4567/the-false-myth-of-encapsulating-data-access-in-the-dal – Sebastian Weber Feb 16 '12 at 13:34

2 Answers2

1

I've written a blog post in the past about exactly this:

Faking your LINQ provider part 1

Steven
  • 166,672
  • 24
  • 332
  • 435
  • Steven, your article got me reading and thinking for an hour or so. Although I understood the architecture part, my lack of knowledge in Linq To SQL and Unit Testing makes me suspect that since I need this for my personal project, the offered approach may be to big of an overhead for me. But perhaps, when you have time, you can write a DataMapper implementation with DbContext (EF4 code-first)? – Maxim V. Pavlov Feb 16 '12 at 14:38
1

Don't use your OR/M everywhere. Use repository classes to abstract away the OR/M and to make it easier to unit test your code. It also removes code duplication and makes it easier to maintain the code in the future.

The upside for you is that you only have to change the repository classes if you need to switch OR/M in the future.

Don't forget that we all pick an OR/M for a reason (the features that your favorite OR/M has). By abstracting away the OR/M behind a generic OR/M layer you also remove the possibility to use those features.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • I agree with you. In the article I'm pointing at, I explain that LINQ is a leaky abstraction. If you truly want to swap OR/M implementations (such as switching from EF to Azure), you can't use IQueryable outside of your Repository classes. – Steven Feb 16 '12 at 22:17