【问题标题】:"EF foreign key (or entity?) not cascading/updating“EF 外键(或实体?)没有级联/更新
【发布时间】:2012-11-27 10:11:09
【问题描述】:

我在 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);
        }
    }

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

更新:不工作。这是我添加到我的控制器的内容......它只是在 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);
        }
    }

【问题讨论】:

  • 请重点关注问题。 JSON 或 WebAPI 与外键有什么关系?我怀疑问题是关于特定的 DAL/ORM ..
  • 我通过 Json 格式的 PUT 发布到 Web-API。很可能其他人以前也遇到过这个问题。
  • 一旦在服务器上接收/解码数据,JSON 和 PUT 就无关紧要了。它们只是解决问题的手段,而不是问题本身。
  • 那你能给我推荐一个新标题吗?这个问题本身有意义吗?我正在将数据发送到服务器,但 db.SaveChanges() 没有保存外键约束
  • 听起来像是 EF 的问题,可能类似于这个问题:stackoverflow.com/questions/3220543/…

标签: c# entity-framework asp.net-mvc-4 asp.net-web-api


【解决方案1】:

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

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

EF 4.3 CF does not update relationships when saving changes

【讨论】:

  • 它将位于 PutTriageRecord 方法中的 db.SaveChanges() 之前。您将需要查看子对象。请记住,WebApi 只是一种传输工具,将数据从 A 获取到 B,然后从 B 回到 A。Visual Studio 将帮助您创建基本的 crud,但这不会扩展 EF 功能。这完全取决于你。
  • 实际上,我所做的代码更改只是在 WorkArea 表中添加了大量条目,而不是更新外键关系...想法?
  • 使用修改状态而不是添加状态。您需要检查对象是否有 ID,然后将其设置为已修改,如果没有,则仅将其设置为已添加。
  • 按照该说明进行操作,仍然无法保存。我认为这是一个已知问题,因为我在网上发现其他人有同样的问题但没有答案。我刚刚放弃了 EF 并使用了直接的 SQL 命令。更快。
猜你喜欢
  • 2018-08-05
  • 2018-12-05
  • 2014-01-17
  • 2022-10-18
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多