我有一個MeterPeak實體,這個實體有一個MeterReading實體作爲外鍵(包含在問題的底部)。 MeterReading實體具有由MeterSiteId和DateTime組成的複合主鍵。爲什麼ModelState.IsValid不能正確地處理外鍵約束?
所以我的理解是,在我的MeterPeak實體中,我必須輸入一個MeterSiteId和一個與現有的MeterReading實體匹配的DateTime以滿足外鍵約束。我不應該被允許鏈接到一個不存在的外鍵。
然而,在MeterPeakController的編輯操作,我有以下代碼
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MeterPeak meterpeak)
{
if (ModelState.IsValid)
{
unitOfWork.MeterPeakRepository.Update(meterpeak);
unitOfWork.Save();
return RedirectToAction("Index");
}
ViewBag.MeterSiteId = new SelectList(unitOfWork.MeterSiteRepository.Get(b => true), "Id", "Location", meterpeak.MeterSiteId);
return View(meterpeak);
}
當我進入一個MeterSiteId和不匹配現有抄表,並試圖挽救我期望的ModelState一個DateTime .IsValid檢查返回false,但它不。它只有當它保存與此錯誤更改的DbContext當獲取到unitOfWork.save()行,它的錯誤
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_dbo.MeterPeaks_dbo.MeterReadings_MeterSiteId_DateTime"
爲什麼ModelState.IsValid沒有得到到dbcontext.save之前發現這個問題失敗?
public class MeterPeak
{
[Key]
public int Id { get; set; }
[ForeignKey("PeakReading"), Column(Order = 1)]
public int MeterSiteId { get; set; }
[ForeignKey("PeakReading"), Column(Order = 2)]
public DateTime DateTime { get; set; }
public int? Rating { get; set; }
public String Note { get; set; }
public virtual MeterReading PeakReading { get; set; }
}
public class MeterReading
{
[Key, Column(Order = 1)]
[Required(ErrorMessage = "Please Select a Meter Site")]
public int MeterSiteId { get; set; }
[Key, Column(Order = 2)]
[Required]
public DateTime DateTime { get; set; }
//This is not the Primary key but I need one unique value to assist in getting records, especially from Javascript
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SingleKey { get; set; }
public virtual MeterSite MeterSite { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double RawLevel { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double RawVelocity { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double RawFlow { get; set; }
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double ValidLevel { get; set; }
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double ValidVelocity { get; set; }
[DisplayFormat(DataFormatString = "{0:#,##0.00000#}", ApplyFormatInEditMode = true)]
public Double ValidFlow { get; set; }
[Range(-1, 3, ErrorMessage = "Rating must be one of the following -1,0,1,2,3")]
public int Rating { get; set; }
public bool? Valid { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
感謝這:-)非常全面的答案 – Mort 2013-05-10 03:24:35
問題 - 我讀的這種方式,似乎'ModelState.IsValid'有一個檢查,以確定模型是否是一個'IValidatableObject',如果是這樣會調用除了其他裝飾器之外,還有'Validate'方法。這是一個準確的陳述,還是我誤解? – 2013-10-25 20:26:01
驗證系統查找數據註釋和「IValidatableObject」接口,並作爲模型綁定過程的一部分執行。任何違反約束條件的都會添加到'ModelState'中。如果錯誤詞典中沒有錯誤,則「ModelState.IsValid」只返回true,否則返回false。 – 2013-10-25 20:50:57