In Entity Framework 6 AddRange method has been introduced. It's great for big inserts because DbSet.Add method always trigger DetectChanges which extremely slows down the process. I've just wanted to use some existing code based on IDbSet interface when realized that it doesn't have AddRange method. It exists only in DbSet class.
I googled a little bit and found this discussion - http://forums.asp.net/t/1978828.aspx?Why+is+there+no+AddRange+method+for+System+Data+Entity+IDbSet+T+ - but there's no clear conclusion about the reason why actually AddRange method does not exist in IDbSet interface.
Is it a bug or is there some good reason for it not to be there? Any ideas?
UPDATE
Here https://entityframework.codeplex.com/workitem/2781 Microsoft gave me an answer:
This is by design. The interface approach wasn't a good one for DbSet because adding members breaks any existing applications that implement the interface.
Given we want to be able to add members to DbSet, we swapped to a base class approach where DbSet is a base class that you can directly mock or inherit.
Here are some links that show how to use DbSet rather than IDbSet:
From the Entity Framework Design Meeting Notes, on May 16, 2013:
The team recognized the potential for breaking changes:
The DbSet classes (generic and non-generic) inherit from a (generic or non-generic) IDbSet interface. IDbSet is intended only for creating test doubles, be these mocks or fakes.
However, in EF6 DbSet has changed in four ways that if reflected in equivalent changes for IDbSet would be breaking changes:
- FindAsync added
- AddRange/RemoveRange added
- Local return type changed to DbLocalView (this change may be reverted anyway)
They discussed a bunch of potential changes in detail, but ultimately decided to avoid the breaking change, and to "make DbSet more mockable":
The decision was to make DbSet more mockable. However, we will not obsolete IDbSet because this would create work for those currently using IDbSet who don’t need to use the new members. We will add guidance to IDbSet indicating that using DbSet is the way to go for new code and, depending on feedback, we may choose to obsolete IDbSet in a future release.
And if you look at the code for IDbSet
, they added comments to the top of the interface:
IDbSet was originally intended to allow creation of test doubles (mocks or fakes) for DbSet. However, this approach has issues in that adding new members to an interface breaks existing code that already implements the interface without the new members.
Therefore, starting with EF6, no new members will be added to this interface and it is recommended that DbSet be used as the base class for test doubles.