.net 一个实体对象不能被多个IEntityChangeTracker实例引用
我有一个模型叫Message。在该模型中有另一个名为Resource的模型的ICollection ResourceSubscribers。当我试图.net 一个实体对象不能被多个IEntityChangeTracker实例引用,.net,asp.net-mvc-3,invalidoperationexception,.net,Asp.net Mvc 3,Invalidoperationexception,我有一个模型叫Message。在该模型中有另一个名为Resource的模型的ICollection ResourceSubscribers。当我试图 public void SaveMessage(List<int> subscribers) { Condition.Requires(model).IsNotNull(); Message model = new Message(); //Some assignments to
public void SaveMessage(List<int> subscribers)
{
Condition.Requires(model).IsNotNull();
Message model = new Message();
//Some assignments to initialize the model
ICollection<Resource> res = new List<Resource>();
foreach (var item in subscribers)
{
res.Add(this.ResourceService.GetResourceById(item));
}
model.ResourceSubscribers = res;
Context.Messages.Add(model);
Context.SaveChanges();
}
public void SaveMessage(列出订户)
{
条件.Requires(model).IsNotNull();
消息模型=新消息();
//一些用于初始化模型的赋值
ICollection res=新列表();
foreach(订阅服务器中的var项)
{
res.Add(this.ResourceService.GetResourceById(项));
}
model.resourcepubers=res;
Context.Messages.Add(模型);
SaveChanges();
}
“Context.Messages.Add(model);”行抛出一个InvalidOperationException,消息为“一个实体对象不能被多个EntityChangeTracker实例引用。”。您是否在
GetResourceById
中使用另一个上下文来获取资源?在这种情况下,这些对象与该上下文关联。执行Context.Messages.Add
时,您尝试将对象与另一个不允许的上下文关联
一起发生的所有相关操作应使用相同的上下文。拥有多个上下文会带来问题。如果您使用相同的上下文,那么最好将上下文用作单例实例 这将确保一个类只有一个实例,并提供对它的全局访问点
检查此项:这是一个老问题,但我想我会发布我的答案,以防它对某人有所帮助 我在MVC代码中遇到了同样的问题,甚至使用了Elad Benda提到的工作单元模式。我发现在控制器调用结束时没有释放我的DbContext资源
using (_DatabaseUow)
{
// your controller code that accesses the database here.
} // When this goes out of scope dispose is called.
然后处理DatabaseUnitOfWork类
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing == true)
{
_ObdDbContext.DetachAll();
_ObdDbContext = null;
_ObdBusinessData = null;
}
}
~DatabaseUnitOfWork()
{
Dispose(false);
}
_ObdBusinessData成员类似于存储库。最后,DbContext派生类中的DetachAll()方法如下所示:
public void DetachAll()
{
var entries = SetTestsOnlineData.Local;
while (entries.Count != 0)
{
TestsOnlineData tod = entries[0];
Tests tro = entries[0].Tests;
List<TestsDtc> dtcs = entries[0].Tests.TestsDtcs.ToList();
foreach (TestsDtc dtc in dtcs)
Detach(dtc);
Detach(entries[0].Tests);
Detach(entries[0]);
tro.TestsDtcs = dtcs;
tro.TestsOnlineData = tod;
tod.Tests = tro;
}
}
public void Detach(object entity)
{
((IObjectContextAdapter)this).ObjectContext.Detach(entity);
}
public void DetachAll()
{
var entries=SetTestsOnlineData.Local;
while(entries.Count!=0)
{
TestsOnlineData tod=条目[0];
测试tro=条目[0]。测试;
列出DTC=条目[0]。Tests.TestsDtcs.ToList();
foreach(dtc中的测试SDTC dtc)
分离(dtc);
分离(条目[0]。测试);
分离(条目[0]);
tro.TestsDtcs=故障诊断码;
tro.TestsOnlineData=tod;
tod.测试=tro;
}
}
公共void分离(对象实体)
{
((IObjectContextAdapter)this.ObjectContext.Detach(实体);
}
我使用实体/对象的特定知识来分离内存中的所有内容。我有一个名为TestsOnlineData的表。它链接到测试,该测试链接到TestsDtc列表。请注意,我保留了这些链接关系,因为对象树的根将被保留,但当其他链接关系分离时,DbContext将释放它们
我本想让它更通用,但它奏效了。我希望这能有所帮助。谢谢你的回答。public void SaveMessage(列表订阅者){Condition.Requires(model).IsNotNull();Message model=new Message();//初始化模型的一些赋值ICollection res=new List();foreach(订阅者中的var项){res.Add(this.Context.Resources.Find(item));}model.ResourceSubscribers=res;Context.Messages.Add(model);Context.SaveChanges();}对我很有效。@dload:如果这是帮助您解决问题的答案,您应该单击复选标记将其标记为已接受。请参阅我过去得到的答案:
基本上,我建议为每个工作单元创建一个新的上下文