2012-07-11 52 views
1

我有一个非常简单的模型,在这里看到:EF4引用完整性异常使用代码优先?

public class Cases 
    { 
    //case data model for call center 
    //implement lists for all related child tables too 

    [Key] 
    public int CasesID { get; set; } 

    public string CaseNumber { get; set; } 

    [Required(ErrorMessage = "Customer is Required")] 
    public int CustomerID { get; set; } 
    public Customer Customer { get; set; } 

    [MaxLength(50)] 
    public string UserName { get; set; } //get user name from the aspnet membership 

    [Required(ErrorMessage = "Case Category is Required")] 
    public int CaseCategoryID { get; set; } 

    [Required(ErrorMessage = "Technician is Required")] 
    public int TechnicianID { get; set; } 
    public Technician Technicians { get; set; } 

    [Required(ErrorMessage = "Engine Model is Required")] 
    public int EngineModelID { get; set; } 
    public EngineModel EngineModel { get; set; } 

    [MaxLength(50)] 
    public string BMSWorkorder { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage = "Status is Required")] 
    public string CaseStatus { get; set; } 

    [MaxLength(50)] 
    public string OpenedBy { get; set; } 

    [Required(ErrorMessage = "Opened Date is Required")] 
    [DataType(DataType.DateTime)] 
    public DateTime? OpenedDate { get; set; } 

    [MaxLength(50)] 
    public string ClosedBy { get; set; } 

    [DataType(DataType.DateTime)] 
    public DateTime? ClosedDate { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage="Caller First Name is Required")] 
    public string CallerFirstName { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage = "Caller Last Name is Required")] 
    public string CallerLastName { get; set; } 

    [MaxLength(10)] 
    [Required(ErrorMessage = "Qualified is Required")] 
    public string Qualified { get; set; } 

    public string Description { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage = "ESN is Required")] 
    public string ESN { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage = "Mileage is Required")] 
    public string Mileage { get; set; } 

    [DataType(DataType.Date)] 
    public DateTime? DateInService { get; set; } 

    [MaxLength(50)] 
    public string ESTR { get; set; } 

    [MaxLength(50)] 
    [Required(ErrorMessage = "EDS is Required")] 
    public string EDS { get; set; } 

    [MaxLength(50)] 
    public string GensetSerialNumber { get; set; } 

    [MaxLength(50)] 
    public string GensetModelNumber { get; set; } 

    //child Case Notes records 
    public virtual ICollection<CaseNotes> CaseNotes { get; set; } 

    //child case attachment records 
    public virtual ICollection<Attachment> Attachments { get; set; } 

    //child case complaint records 
    public virtual ICollection<CaseComplaint> CaseComplaint { get; set; } 

    //tracking fields 
    public DateTime? CreatedOn { get; set; } 
    [MaxLength(50)] 
    public string CreatedBy { get; set; } 
    public DateTime? ModifiedOn { get; set; } 
    [MaxLength(50)] 
    public string ModifiedBy { get; set; } 
    } 

一个案例可以有很多CaseNotes,附件和CaseComplaints。外键是技术人员,客户和EngineModel。

直到今天,所有这一切都很好与添加和编辑模型。现在,我得到了 “”发生了参照完整性约束冲突:定义参照约束的属性值在关系中的主体和从属对象之间不一致“ 仅当尝试更新案例记录时编辑视图。由于所有必填字段都已填充,因此创建并插入是正确的。 这为什么刚刚开始发生。仅供参考,如果我检查模型只是为了调用context.SaveChanges,我注意到所有的数据都看起来正确,FK值被填充,但外键类(技术人员)的导航属性中的数据几乎看起来像它认为我试图插入这些类中的一个新的纪录......

这里是我的控制器编辑操作:

public ActionResult Edit(int id) 
    { 
     Cases cases = db.Cases.Find(id); 
     db.Entry(cases).Reference(x => x.Customer).Load(); 
     db.Entry(cases).Collection(x => x.CaseComplaint).Load(); 
     db.Entry(cases).Collection(x => x.CaseNotes).Load(); 
     db.Entry(cases).Reference(x => x.Technicians).Load(); 

     GetCaseCategoryLookup(cases.CaseCategoryID); 
     GetEngineModelLookup(cases.EngineModelID); 
     GetTechnicianLookup(cases.TechnicianID); 
     GetQualifiedList(cases.Qualified); 
     GetCaseStatusList(cases.CaseStatus); 

     return View(cases); 
    } 

    // 
    // POST: /Cases/Edit/5 

    [HttpPost] 
    public ActionResult Edit(Cases cases) 
    { 
     if (ModelState.IsValid) 
     { 
     AppHelpers help = new AppHelpers(); 

      if (cases.CaseStatus == "CLOSED") 
       { 
       cases.ClosedBy = "USER"; 
       cases.ClosedDate = help.GetEasternTime(); 
       } 
      cases.ModifiedBy = "USER"; 
      cases.ModifiedOn = help.GetEasternTime(); 

      db.Entry(cases).State = EntityState.Modified; 
      db.SaveChanges(); 

     } 

     return RedirectToAction("Index"); 
    } 
+0

“但是,导航属性中的数据几乎看起来像它认为我试图插入一个新的记录在这些类*”:那么,这是一个视图和模型绑定问题或导航属性值来自哪里? – Slauma 2012-07-11 19:12:31

+0

我是一个noob,所以你将不得不忍受我。技术人员和客户以及EngineModel上面的属性应该只是允许我显示子数据,但好像它们被标记为随着案例类一起被修改。 – Ryan 2012-07-11 19:27:19

+0

我认为如果您可以显示发布后操作以及如何处理数据直至SaveChanges会很有帮助。 – Slauma 2012-07-11 19:30:21

回答

2

只是为了说明什么异常意味着:

参照完整性发生约束违规:属性 值tha t定义了关系中的主体和从属对象之间的参照约束不一致 。

您的控制器发布后的主要对象是cases.Technicians,依赖项为cases。 “定义参照约束的属性值”是从属对象中的外键,即cases.TechnicianID,另一边是主体的主键,即cases.Technicians.TechnicianID

例外说明这两个值是不同的:cases.TechnicianID != cases.Technicians.TechnicianID但当您更新实体时它们必须相同。

我不知道你的观点究竟应该做什么。你只能编辑cases实体或cases.Technicians属性吗?或者您是否只能指定一个新的现有技术人员为cases?如果后者是这种情况,我很厌烦为什么模型绑定器创建了一个cases.Technicians实例,因为不应该有任何表单域来保存cases.Technicians的属性。要指定另一个现有技术人员,只需将外键cases.TechnicianID绑定到表单域即可。

在您需要确保任何cases.TechnicianIDcases.Technicians.TechnicianID具有相同的价值无论如何或cases.Techniciansnull。这取决于视图应该做什么以及需要更新哪些数据 - 只有cases属性或cases.Technicians属性也是如此。

+0

感谢您的时间。该视图基本上是添加和编辑案例。现有技术人员(技术人员)可以通过下拉列表选择并与案例相关联。我使用案件的原因是技术人员的财产是显示案件的技术人员信息。所以,对于EF而言,我有点困惑,因为必须确保技术人员ID和案例。技术人员。技术人员ID是一样的。我不希望任何更新的案件。技术人员从案件的意见。 – Ryan 2012-07-12 13:53:56

+0

@Ryan:你也许可以解决这个问题,然后在post操作开始时将'cases.Technicians'设置为'null'。但这是一种诡计,奇怪的是'cases.Technicians'不是'null','cases.Technicians.TechnicianID'是错误的。 BTW:在大多数情况下,更好的方法是将ViewModels用于MVC视图,而不是直接使用实体。您的ViewModel包含了应该编辑的属性,并且在后期操作中映射了视图模型,该视图模型以一种恰好属性得到更新所需的方式回传给实体。 – Slauma 2012-07-12 14:26:01

+0

我认为,而不是黑客,我宁愿做正确的方式,你不觉得吗?当我学习如何使用视图模型时,你会监视这个线程吗?看起来奇怪的是,像父子记录与孩子关联这样的简单操作会产生问题。 – Ryan 2012-07-12 14:35:13