Add AddRange() and RemoveRange() to IDbSet<T>?

Topics: EF Runtime
Jun 27, 2013 at 2:50 PM
Hi,

I've just been reviewing the changes in EF6, and I note that AddRange() and RemoveRange() are only on the DbSet/DbSet<T> classes, and not on the IDbSet<T> interface.

Would it be possible to either:

a) Add these methods to IDbSet<T>;
or b) Add a new interface (that derives from IDbSet<T>?) that adds these methods if the breaking change a would introduce is not acceptable?

Some of my data access code wraps access to IDbSet<T> behind another interface, and it would be nice to expose AddRange() and RemoveRange() on this custom wrapping interface after updating to EF6 by just calling into the IDbSet<T> it wraps, rather than having to cast it to DbSet<T> first. It makes the wrapping implementation a bit cleaner if there's an interface as it wouldn't need to introduce a dependency on a specific EF concrete type.

Thanks,
Martin
Coordinator
Jun 27, 2013 at 9:56 PM
Hello Martin,

We originally had a bug for exactly that: #1086. But after a long discussion on what to do about these and other new methods that could potentially make it into IDbSet<T> (see details of the in the design meeting notes for May 16) we ended up deciding to make DbSet<T> mockable instead of keeping adding stuff to IDbSet<T>.

Regarding the assumption that taking a dependency on an EF interface would make your code cleaner than taking a dependency on an EF class, we looked at the common genuine motivations for using interfaces rather than classes and we came to the conclusion that they don't really apply in this case:
  • You are trying to create a test double for an existing infrastructure abstraction rather than trying to decouple different parts of your application code.
  • An interface that implemented all the methods on DbSet<T> would be little more than DbSet<T> with a different name
If there are reasons this is not the best decision we would like to learn about them.

Thanks,
Diego
Oct 11, 2013 at 11:03 PM
divega wrote:
Hello Martin,

We originally had a bug for exactly that: #1086. But after a long discussion on what to do about these and other new methods that could potentially make it into IDbSet<T> (see details of the in the design meeting notes for May 16) we ended up deciding to make DbSet<T> mockable instead of keeping adding stuff to IDbSet<T>.

Regarding the assumption that taking a dependency on an EF interface would make your code cleaner than taking a dependency on an EF class, we looked at the common genuine motivations for using interfaces rather than classes and we came to the conclusion that they don't really apply in this case:
  • You are trying to create a test double for an existing infrastructure abstraction rather than trying to decouple different parts of your application code.
  • An interface that implemented all the methods on DbSet<T> would be little more than DbSet<T> with a different name
If there are reasons this is not the best decision we would like to learn about them.

Thanks,
Diego
So in EF 6 (rc1), the DbSet Is mockable?

I tried to mock it up but it still dies and says it can't be mockedup.
Coordinator
Oct 12, 2013 at 12:17 AM
chobo2,

It is possible that not all the changes necessary made it for RC1. Could you try with our latest nightly build?

Otherwise can you be more specific about how it "dies"? :)

Thanks,
Diego
Oct 12, 2013 at 1:48 AM
divega wrote:
chobo2,

It is possible that not all the changes necessary made it for RC1. Could you try with our latest nightly build?

Otherwise can you be more specific about how it "dies"? :)

Thanks,
Diego
I was trying to get it to work with autofixture & moq but gave up(I would have thought it would be alot easier to mockup EF).

I am now trying to follow the tutorial on it

http://msdn.microsoft.com/en-US/data/dn314429#service

but still have lots of problems what I posted on Stack.

http://stackoverflow.com/questions/19328224/how-to-mockup-enityframework-6-with-moq-autofixture
Coordinator
Oct 12, 2013 at 2:07 AM
Thanks for the information. Can you confirm that you are getting these exceptions with our nightly builds? FWIW, the type loading exception at the bottom of your SO makes me think that the mocking framework you are using has a bug because it fails to preserve the generic constraint when it tries to override Create.
Oct 12, 2013 at 3:57 AM
divega wrote:
Thanks for the information. Can you confirm that you are getting these exceptions with our nightly builds? FWIW, the type loading exception at the bottom of your SO makes me think that the mocking framework you are using has a bug because it fails to preserve the generic constraint when it tries to override Create.
Ok, I will test again. I am trying another computer just to make sure as well as my computer is not picking up the unit tests in the test explorer so I can't use MSTest and been using Nunit(this is what I use but I wanted to rule it out and use exactly what was in the tutorial)
Oct 12, 2013 at 7:02 AM
divega wrote:
Thanks for the information. Can you confirm that you are getting these exceptions with our nightly builds? FWIW, the type loading exception at the bottom of your SO makes me think that the mocking framework you are using has a bug because it fails to preserve the generic constraint when it tries to override Create.
Hey,

You are right it was moq that was failing. When I installed Autofixture they are using moq 3 instead of moq 4 and of course I thought I just had the latest version and it was not till I made a new project and just installed moq package directly I realized this.

I put a bug notice up for Autofixture and hopefully if they do fix it, it will just work with EF 6.

I still have to play around with everything else but up to "Testing non-query scenarios" in the tutorial works so far.
Coordinator
Oct 12, 2013 at 7:11 AM
Great to hear! Thanks for the update.