尝试通过 context.AttachTo(...)
附加已附加到给定上下文的对象时,出现以下错误:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
有没有一种方法可以实现以下目标:
context.IsAttachedTo(...)
干杯!
编辑:
Jason 概述的扩展方法很接近,但它不适用于我的情况。
我正在尝试使用另一个问题的答案中概述的方法做一些工作:
我的代码看起来有点像这样:
var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();
这工作正常,除非我使用相同的方法为该用户执行其他操作并尝试附加虚拟 User
对象。这失败了,因为我之前已经附加了该虚拟用户对象。我如何检查这一点?
最佳答案
这是我最终得到的结果,效果非常好:
public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
where T : IEntityWithKey
{
ObjectStateEntry entry;
// Track whether we need to perform an attach
bool attach = false;
if (
context.ObjectStateManager.TryGetObjectStateEntry
(
context.CreateEntityKey(entitySetName, entity),
out entry
)
)
{
// Re-attach if necessary
attach = entry.State == EntityState.Detached;
// Get the discovered entity to the ref
entity = (T)entry.Entity;
}
else
{
// Attach for the first time
attach = true;
}
if (attach)
context.AttachTo(entitySetName, entity);
}
您可以按如下方式调用它:
User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);
这非常有效,因为它就像 context.AttachTo(...)
一样,只不过您每次都可以使用我上面引用的 ID 技巧。您最终会得到之前附加的对象或附加的您自己的对象。在上下文中调用 CreateEntityKey
可确保它良好且通用,并且即使使用复合键也无需进一步编码(因为 EF 已经可以为我们做到这一点!)。
编辑,十二年后(2021 年 12 月)...噢!
这是我在 EF Core 中使用的内容:
public static class EfExtensions
{
public static T AttachToOrGet<T>(this DbContext context, Func<T,bool> predicate, Func<T> factory)
where T : class, new()
{
var match = context.Set<T>().Local.FirstOrDefault(predicate);
if (match == null)
{
match = factory();
context.Attach(match);
}
return match;
}
}
用法:
var item = db.AttachToOrGet(_ => _.Id == someId, () => new MyItem { Id = someId });
您可以重构它以使用实体 key ,但这足以让任何人开始!
关于.net - 是否可以检查对象是否已附加到 Entity Framework 中的数据上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1715501/