简体   繁体   English

EF 4.0自我跟踪实体,预期更新正在转换为插入

[英]EF 4.0 Self-Tracking Entities, intended updates are being translated into inserts

Let's assume that the below method lives in a WCF service. 我们假设下面的方法存在于WCF服务中。 The UI retrieved an instance of the Status object, and makes a subsequent call to the service using this method. UI检索Status对象的实例,并使用此方法对服务进行后续调用。 Instead of assigning the status to the user as I would expect, it attempts to insert the status. 它不是像我期望的那样将状态分配给用户,而是尝试插入状态。 What am I doing wrong? 我究竟做错了什么?

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();
}

Try this instead: 试试这个:

        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();
        }

Here's a tutorial on CRUD with Entity Framework if you're interested. 如果您有兴趣,这里有一个关于CRUD with Entity Framework教程

The problem is that you are working with attached user. 问题是您正在使用附加用户。 When the STE is attached to the context it behaves exactly in the same way as any other entity. 当STE附加到上下文时,它的行为与任何其他实体完全相同。 More over its self tracking mechanism is not activated. 其自我跟踪机制的更多内容未激活。 So you must attach the status to the context before you set it to the user or it will be tracked as a new entity which has to be inserted: 因此,在将状态设置为用户之前,必须将状态附加到上下文,否则它将作为必须插入的新实体进行跟踪:

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

    context.Attach(status);
    user.Status = status;

    context.SaveChanges();
}

Have to write an answer because I can't yet comment on another answer (rep score < 50) [ something weirdly not right about that, but I get why it's like that ] because I wanted to add some clarity to @Ladislav's answer. 必须写一个答案,因为我还不能评论另一个答案(代表得分<50)[ 有些奇怪的不正确,但我明白为什么就是这样 ]因为我想为@ Ladislav的回答添加一些清晰度。

The Status object coming in from the WCF call did not come from the same context you are using to find the User object, so the tracking code is not fixed up with that context. 来自WCF调用的Status对象并非来自您用于查找User对象的相同context ,因此跟踪代码不会与该上下文一起修复。 This is why attaching it will allow you to save the assignment without the context thinking that status is a new entity requiring an insert into the database. 这就是为什么附加它将允许您保存赋值而不考虑context认为status是需要插入数据库的新实体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM