Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以停止实体框架;“修理”;保存更改后的关系?_C#_.net_Entity Framework 4.3.1 - Fatal编程技术网

C# 是否可以停止实体框架;“修理”;保存更改后的关系?

C# 是否可以停止实体框架;“修理”;保存更改后的关系?,c#,.net,entity-framework-4.3.1,C#,.net,Entity Framework 4.3.1,我从EntityFramework4.3.1中得到了这个例外(顺便说一句,是从Visual Studio 2010中针对.NET4构建的ASP.NETMVC3Web应用程序中得到的): System.InvalidOperationException:已成功提交对数据库的更改,但更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:无法将对象添加到对象上下文中。该对象的EntityKey有一个ObjectStateEntry,它指示该对象已参与不同的关系 我在谷歌上

我从EntityFramework4.3.1中得到了这个例外(顺便说一句,是从Visual Studio 2010中针对.NET4构建的ASP.NETMVC3Web应用程序中得到的):

System.InvalidOperationException:已成功提交对数据库的更改,但更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:无法将对象添加到对象上下文中。该对象的EntityKey有一个ObjectStateEntry,它指示该对象已参与不同的关系

我在谷歌上搜索了一下,得出了以下结论(在msdn上):

Jeff Derstadt(公认的答案)说:

然后调用SaveChanges时,上下文将保留更改,然后尝试修复状态项。执行此操作时,它将执行“密钥修复”,其中is将临时EntityKeys转换为完整EntityKeys。在这种情况下,临时密钥TKP2现在将等于P2的密钥。上下文尝试将状态管理器中的键条目“升级”为完整的实体条目,并在此过程中修复图形。这里发生异常是因为存在冲突:P1.party=P2,因此P2.party应该=P1,但由于添加了项目,P2.party已经等于P3,EntityReference不能有多个值。不幸的是,在数据库保存之前并不总是能够检测到这种情况,因为临时EntityKey不等同于完整EntityKey,因此我们无法识别类似这样的将来的合并

我的想法有点“肮脏”,所以我的问题是


由于我并不真正关心对象图在保存更改(即我的请求结束,因此无论如何都会被丢弃)之后的样子,并且数据已经被插入(并且在调试器中让对象图继续运行后,当我在SQL Server中查看对象图时,实际上是完全正常的)——有没有办法告诉Entity Framework不要执行此步骤(因此不会出现此异常,并且可能也会节省一些时间)?

如果需要更好的帮助,您应该发布一些代码

尽管如此,我还是发现自己在与这些错误作斗争,并得出了一个基本事实:如果您引用的是数据库中已经存在的内容,请务必引用它。不要只使用键或代码,请使用DbContext中表示的实际对象。您可以使用DbContext.Entry()方法查找它们

另一方面,如果原始对象和引用对象都是在运行时创建的,请确保为它们提供了唯一的ID,并且实体框架(而不是数据库)在运行时知道该ID可能是对象A引用的对象B的运行时ID不等于同一对象存储在数据库中后获得的ID


正如我所说,如果您愿意发布一些代码,我们可能会提供更好的帮助;)

没有正式的方法可以做到这一点,但请尝试以下方法:

private static readonly Lazy<MethodInfo> internalDeleteMethod = new Lazy<MethodInfo>(
    () => typeof(ObjectContext).Assembly.GetType("System.Data.Objects.EntityEntry").GetMethod("Delete", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(bool) }, null)); 


public static void Delete<TEntity>(Func<DbContext> dbContextFactory, TEntity entity,
    Func<DbContext, IEnumerable<DbEntityValidationResult>> onSaving = null,
    Action<DbContext> onSaved = null,
    bool referenceFixup = true)
        where TEntity : class
{
    Guard.ArgumentNotNull(dbContextFactory, "dbContextFactory");
    Guard.ArgumentNotNull(entity, "entity");
    onSaving = onSaving ?? (_ => null);
    onSaved = onSaved ?? (_ => { });

    using (var dbContext = dbContextFactory())
    {
        var set = dbContext.Set<TEntity>();
        set.Attach(entity);

        var entry = ((IObjectContextAdapter)dbContext).ObjectContext.ObjectStateManager.GetObjectStateEntry(entity);
        internalDeleteMethod.Value.Invoke(entry, new object[] { referenceFixup });

        dbContext.SaveChanges();
     }
 }
private static readonly Lazy internalDeleteMethod=new Lazy(
()=>typeof(ObjectContext.Assembly.GetType(“System.Data.Objects.EntityEntry”).GetMethod(“Delete”,BindingFlags.Instance | BindingFlags.NonPublic,null,new[]{typeof(bool)},null));
公共静态无效删除(Func dbContextFactory、TEntity实体、,
Func onSaving=null,
保存的操作=空,
bool referenceFixup=true)
地点:班级
{
ArgumentNotNull(dbContextFactory,“dbContextFactory”);
Guard.ArgumentNotNull(实体,“实体”);
onSaving=onSaving??(=>null);
onSaved=onSaved??({});
使用(var dbContext=dbContextFactory())
{
var set=dbContext.set();
集合。附加(实体);
var entry=((IOObjectContextAdapter)dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntry(实体);
internalDeleteMethod.Value.Invoke(条目,新对象[]{referenceFixup});
dbContext.SaveChanges();
}
}

当我尝试实体框架时,我在尝试做一些不标准的事情时遇到了很多麻烦。我发现NHibernate更容易使用。