jos*_*ley 83 .net entity-framework
尝试通过以下方式附加已附加到给定上下文的对象时,我收到以下错误context.AttachTo(...):
ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象.
有没有办法实现以下方面:
context.IsAttachedTo(...)
干杯!
编辑:
Jason概述的扩展方法很接近,但它对我的情况不起作用.
我正在尝试使用另一个问题的答案中概述的方法做一些工作:
如何使用Linq to Entities*从表中删除一行或多行而不先检索行?
我的代码看起来有点像这样:
var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();
这工作正常,除非我为该用户执行其他操作,我使用相同的方法并尝试附加虚拟User对象.这失败是因为我之前已经附加了这个虚拟用户对象.我该如何检查?
jos*_*ley 56
这就是我最终得到的结果,效果非常好:
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已经为我们做了!).
Mos*_*osh 46
一种更简单的方法是:
 bool isDetached = context.Entry(user).State == EntityState.Detached;
 if (isDetached)
     context.Users.Attach(user);
jas*_*son 18
尝试这种扩展方法(这是未经测试的,并且是袖手旁观的):
public static bool IsAttachedTo(this ObjectContext context, object entity) {
    if(entity == null) {
        throw new ArgumentNullException("entity");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}
鉴于您在编辑中描述的情况,您可能需要使用以下重载来接受EntityKey而不是对象:
public static bool IsAttachedTo(this ObjectContext, EntityKey key) {
    if(key == null) {
        throw new ArgumentNullException("key");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(key, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}
要构建适合EntityKey您的情况,请使用以下指南:
EntityKey key = new EntityKey("MyEntities.User", "Id", 1);
您可以使用属性(来自接口)EntityKey从现有实例获取.UserUser.EntityKeyIEntityWithKey
使用您要检查的对象的实体键:
var entry = context.ObjectStateManager.GetObjectStateEntry("EntityKey");
if (entry.State == EntityState.Detached)
{
  // Do Something
}
善良,
担