Entity framework 在Entity Framework 6中是否可以将ObjectSet转换为DbSet?

Entity framework 在Entity Framework 6中是否可以将ObjectSet转换为DbSet?,entity-framework,dbset,objectset,Entity Framework,Dbset,Objectset,我正在将WPF应用程序从使用.Net4/EF 4.4升级到.Net4.5/EF 6.1。升级后,我将使用DbContext(因为ObjectContext没有POCO生成器) 应用程序使用Repository/UnitOfWork模式访问实体框架,在升级之前,我可以将ObjectSet.MergeOption设置为OverwriteChanges(在Repository类中),但DbSet类没有此功能。但是,我知道我可以通过使用IObjectContextAdapter从DbContext访问O

我正在将WPF应用程序从使用.Net4/EF 4.4升级到.Net4.5/EF 6.1。升级后,我将使用DbContext(因为ObjectContext没有POCO生成器)

应用程序使用Repository/UnitOfWork模式访问实体框架,在升级之前,我可以将ObjectSet.MergeOption设置为OverwriteChanges(在Repository类中),但DbSet类没有此功能。但是,我知道我可以通过使用IObjectContextAdapter从DbContext访问ObjectSet。(见下面的代码)。但是,在创建的ObjectSet上设置MergeOption似乎不会反映回DbSet

所以我的问题是:有没有办法将ObjectSet转换回DbSet(保存MergeOption设置)

这是存储库类的一部分:

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;


    }
}
public类SqlRepository:IRepository其中T:class,IEntity
{
受保护的DbSet-DbSet;
公共SqlRepository(DbContext上下文)
{
var objectContext=((IObjectContextAdapter)context).objectContext;
var set=objectContext.CreateObjectSet();
set.MergeOption=MergeOption.OverwriteChanges;
dbSet=context.Set();
//我想这样做:dbSet=(dbSet)set;
}
}

虽然不是对您问题的直接回答,但我提出了一个基于T4的解决方案,解决了DbSet中无法访问的EF监督合并选项。从你的问题来看,这就是你想要的

在默认上下文中,T4生成器生成了如下内容:

public virtual DbSet<Person> Persons { get; set; }
public virtual DbSet<Address> Addresses { get; set; }
或者你可以(像我一样)写一些类似的东西

Database.MergeOption = MergeOption.OverwriteChanges;
使用现有的Get方法刷新实体的加载,但现在将覆盖所有附加的实体


需要注意的是,如果在进行更改之前加载AsNoTracking,则需要重新附加或最好使用OverwriteChanges重新加载,以确保拥有最新的实体。

有一个POCO生成器:@ErikEJ是的,我知道,但我认为它不会创建POCO,而是创建EntityObject派生的类?当我使用它时,它只创建了xxModel.tt文件,而不是像在T4的EF 4.4版本中那样创建了xxModel.Context.tt文件。对不起,你是对的……真的有点开玩笑,他们甚至没有考虑对现实世界的影响就破坏了所有MergeOption功能applications@TomDeloford是 啊我真的很难找到另一种方法来做到这一点。我想很多其他人都需要覆盖更改选项。谢谢你的例子。当我有时间的时候,我会更仔细地看一看。。。自从我上任后,我不得不转向其他事情。我记得对我来说困难的事情之一是,我试图升级的应用程序使用了一种非常通用的方法来处理EF(存储库/Uow),这使得很难利用EF的一些更具体的功能。不过,再次感谢你的建议。
public class DataContextBase
{

    /// <summary>
    /// Gets or sets the forced MergeOption. When this is set all queries 
    /// generated using GetObjectSet will use this value
    /// </summary>
    public MergeOption? MergeOption { get; set; }


/// <summary>
/// Gets an ObjectSet of type T optionally providing a MergeOption.
/// <remarks>Warning: if a DataContext.MergeOption is specified it will take precedence over the passed value</remarks>
/// </summary>
/// <typeparam name="TEntity">ObjectSet entity Type</typeparam>
/// <param name="mergeOption">The MergeOption for the query (overriden by DataContext.MergeOption)</param>
protected IQueryable<TEntity> GetObjectSet<TEntity>(MergeOption? mergeOption = null) where TEntity : class
{
    var set = Context.CreateObjectSet<TEntity>();
    set.MergeOption = MergeOption ?? mergeOption ?? MergeOption.AppendOnly;

    return set;
}
 public static class CustomQueryImplentations
 {
        public static IQueryable<Person> QueryImplementation(this IQueryable<Person> source)
        {
            return source
                .Include(r => r.Addresses)
                .OrderByDescending(c => c.Name);
        }
  }
//just load a simple list with no tracking (Fast!)
var people = Database.GetPersons(MergeOption.NoTracking);

//user wants to edit Person so now need Attached Tracked Person (Slow)
var peson = Database.GetPersons(MergeOption.OverwriteChanges).FirstOrDefault(p => p.PersonID = 1);

//user makes changes and on another machine sometime later user clicks refresh
var people = Database.GetPersons(MergeOption.OverwriteChanges);
Database.MergeOption = MergeOption.OverwriteChanges;
Database.MergeOption = null;