I am working on upgrading a WPF application from using .Net4/EF 4.4 to .Net4.5/EF 6.1. After the upgrade I will use DbContext (since there was no POCO-generator for ObjectContext).
The application use a Repository/UnitOfWork-pattern to access Entity Framework, and before the upgrade I could set the ObjectSet.MergeOption to OverwriteChanges (in the repository-class), but the DbSet-class does not have this feature. However, I know that I can get to a ObjectSet from the DbContext by using the IObjectContextAdapter. (See code below). But it seems that setting the MergeOption on the created ObjectSet will not reflect back to the DbSet.
So my question is this: is there any way to convert the ObjectSet back to a DbSet (conserving the MergeOption-setting)?
This is some of the repository class:
public class SqlRepository<T> : IRepository<T> where T : class, IEntity
{
protected DbSet<T> dbSet;
public SqlRepository(DbContext context)
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var set = objectContext.CreateObjectSet<T>();
set.MergeOption = MergeOption.OverwriteChanges;
dbSet = context.Set<T>();
//I would like to do something like this: dbSet = (DbSet)set;
}
}
Although not a direct answer to your question, I have come up with a T4 based solution to the EF oversight around MergeOption not being accessible in DbSet. It seems from your question this is what you are looking for?
In the default Context you have something generated by the T4 generator like:
etc.
My approach is to edit the T4 to add Getters for each Entity that provide direct access the ObjectSet as an IQueryable:
Then in a base DataContext
By creating a default Extension method for an IQueryable as below you can optionally add your own implenations of QueryImplementation for each table/type so that all users of your table get sorting or includes etc. (this part is not required to answer the question but its useful anyway)
So for example you could add the following to always Include Addresses when calling GetPersons()
Finally:
Or you can (as I have) write something like
refresh loads of entities using existing Get methods but will now ALL overwrite Attached entities
Something to note is that if you load AsNoTracking before you make changes you need to either Re-Attach or probably better reload with OverwriteChanges to ensure you have the latest Entity.