EF 4.0自我跟踪实体,预期的更新正在被翻译成插入

本文关键字:更新 翻译 插入 自我 跟踪 实体 EF | 更新日期: 2023-09-27 17:49:51

让我们假设下面的方法存在于WCF服务中。UI检索Status对象的实例,并使用此方法对服务进行后续调用。它没有像我期望的那样将状态分配给用户,而是尝试插入状态。我做错了什么?

void Method(Status status)
{
    //not sure if this is even needed, the status never changed
    context.Statuses.ApplyChanges(status);
    //get the first user from the database
    User user = context.Users.Where(u => u.Id = 1).First();
    //set user status to some existing status
    user.Status = status;
    //this throws an exception due to EF trying to insert a new entry
    //into the status table, rather than updating the user.StatusId column.
    context.SaveChanges();
}

EF 4.0自我跟踪实体,预期的更新正在被翻译成插入

问题是您正在使用附加用户。当STE附加到上下文时,它的行为方式与任何其他实体完全相同。更过其自跟踪机制未被激活。因此,在将状态设置为用户之前,必须将其附加到上下文,否则它将被跟踪为必须插入的新实体:

void Method(Status status)
{
    User user = context.Users.Where(u => u.Id = 1).First();
    context.Attach(status);
    user.Status = status;
    context.SaveChanges();
}

试试这个:

        using (Entities ctx = new Entities())
        {
            ctx.Statuses.Attach(status);
            ObjectStateEntry entry = ctx.ObjectStateManager.GetObjectStateEntry(status);
            entry.ChangeState(EntityState.Modified);
            //get the first user from the database
            User user = ctx.Users.Where(u => u.Id = 1);
            //set user status to some existing status
            user.StatusID = status.StatusID;
            ctx.SaveChanges();
        }

如果你感兴趣,这里有一个关于实体框架的CRUD教程。

必须写一个答案,因为我还不能评论另一个答案(rep score <50) [这有点奇怪,但我明白为什么是这样的]因为我想给@Ladislav的答案增加一些清晰度。

来自WCF调用的Status对象并非来自您用于查找User对象的相同context,因此跟踪代码未与该上下文固定。这就是为什么附加它将允许您保存分配,而不会让context认为status是一个需要插入数据库的新实体。