1

我在 MVC4 中使用 WebAPI。我有一个简单的表单,它通过 PUT 请求将数据提交给 API。数据到达并被很好地序列化,一切看起来都很棒,除了任何有外键的地方都没有更新。是的,外键存在。

我有以下课程:

public class TriageRecord
{
    [Key]
    public Int64 PKEY { get; set; }
    public DateTime DateAdded { get; set; }
    public DateTime DateUpdated { get; set; }
    public Int64? RecordSource_Id { get; set; }  
    public Int64? AssignedVolunteer_Id { get; set; }  
    public string FacebookID { get; set; }
    public Int64? VANID { get; set; }
    public Int64? NationBuilderID { get; set; }
    public DateTime? DateVanSubmitted { get; set; }
    public Int64? FollowUpLevel_Id { get; set; } 
    public bool? Complete { get; set; }


    public string First { get; set; }
    public string Mid { get; set; }
    public string Last { get; set; }
    public string Email { get; set; }
    public string Address1 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip5 { get; set; }


    public string HomePhone { get; set; }
    public string CellPhone { get; set; }

    public Int32? EmployeeStatus { get; set; }
    public string StoreNumber { get; set; }
    public virtual WorkArea WorkArea { get; set; }   //put your focus here
    public virtual Department Department { get; set; }
    public virtual Shift Shift { get; set; }


   }

这是我通过表单更新的 WorkArea 类。

public class WorkArea
{
    [Key]
    public Int64 Id { get; set; }
    [StringLength(200)]
    public string WorkAreaName { get; set; }
}

这是我发布的 JSON,它非常好地到达我的 API 控制器:

   var saveRecord = function() {
            var record = {
                "PKEY": $("#PKEY").val(),
                "DateAdded": $("#DateAdded").val(),
                "DateUpdated": "@DateTime.Now.ToString()",
                "First": $("#First").val(),
                "Mid": $("#Mid").val(),
                "Last": $("#Last").val(),
                "RecordSource_Id": $("#RecordSource_Id").val(),
                "AssignedVolunteer_Id": $("#AssignedVolunteer_Id").val(),
                "FacebookID": $("#FacebookID").val(),
                "VANID": $("#VANID").val(),
                "NationBuilderID": $("#NationBuilderID").val(),
                "DateVanSubmitted": Date.now(),
                "FollowUpLevel_Id": $("#FollowUpLevel_Id").val(),
                "Complete": $("#Complete").val(),
                "Email": $("#Email").val(),
                "Address1": $("#Address1").val(),
                "City": $("#City").val(),
                "State": $("#State").val(),
                "Zip5": $("#Zip5").val(),
                "HomePhone": $("#HomePhone").val(),
                "CellPhone": $("#CellPhone").val(),
                "EmployeeStatus": $("#EmployeeStatus").val(),
                "StoreNumber": $("#StoreNumber").val(),
                "WorkArea": {
                    "Id": 1,
                    "WorkAreaName": "GM"
                },
                "Department": $("#Department").val(),
                "Shift": $("#Shift").val()                       
            };

它被序列化并到达我的控制器,当我设置断点时,我可以看到 WorkArea (Models.WorkArea) 填充了 Id = 1 & WorkAreaName = "GM"

所以这是我的控制器:

  public HttpResponseMessage PutTriageRecord(long id, TriageRecord triagerecord)
    {
        if (id == triagerecord.PKEY)  //breakpoint here shows triagerecord contains workarea values
        {                
            db.Entry(triagerecord).State = EntityState.Modified;                
            try
            {                    
            db.SaveChanges();  //changes get saved for everything (ie, first name) but not workarea...
            }
            catch (DbUpdateConcurrencyException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }
    }

除了 WorkArea 之外,我的 TriageRecord 中的所有内容都已更新……为什么?

更新:不工作。这就是我添加到控制器中的内容......它只是在 WorkAreas 表中不断创建大量的整体。

  public HttpResponseMessage PutTriageRecord(long id, TriageRecord triagerecord)
    {
        if (id == triagerecord.PKEY)  //breakpoint here shows triagerecord contains workarea values
        {                
            db.Entry(triagerecord).State = EntityState.Modified;                
            try
            {      
                db.TriageRecords.Attach(triagerecord);   //attach
                db.Entry(triagerecord.WorkArea).State = EntityState.Added;   //add           
            db.SaveChanges();  //WORKS!
            }
            catch (DbUpdateConcurrencyException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }
        else
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }
    }
4

1 回答 1

1

您需要调用 Attach 并将子对象的状态设置为已添加。它与 WebApi 没有任何关系,这就是 EF 在处理分离对象时的工作方式(例如,当您将它们发送到客户端并返回时)。db 上下文跟踪是更改,因此当您使用分离的对象时,它不会知道已添加的内容会自动修改。

“如果你不调用 Attach,孩子们会保持分离状态,直到调用 SaveChanges,EF 将假定它们是新实体(因为它们没有附加到上下文)并将它们的状态设置为已添加。然后它们将被插入到数据库中。”

EF 4.3 CF 在保存更改时不更新关系

于 2012-12-10T01:32:26.027 回答