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 に答える