2011-08-22 97 views
1

嗨之前,我有一個Invoice類型,如:實體框架檢查唯一插入

public class Invoice : IEntity, IValidatableObject 
    { 
     public virtual int Id { get; set; } 

     [Required(ErrorMessage = "Invoice Number is a required field.")] 
     [Display(Name = "Invoice Number:")] 
     public virtual string InvoiceNumber { get; set; } 

     [Required(ErrorMessage = "Invoice Date is a required field.")] 
     [Display(Name = "Invoice Date:")] 
     [DataType(DataType.Date)] 
     public DateTime? InvoiceDate { get; set; } 

     [Required(ErrorMessage = "Organisation is a required field.")] 
     [Display(Name = "Organisation:")] 
     public int OrganisationId { get; set; } 

     [Required(ErrorMessage = "Region is a required field.")] 
     [Display(Name = "Region:")] 
     public virtual int? AreaId { get; set; } 

     [Required(ErrorMessage = "Total (Exc. GST) is a required field.")] 
     [Display(Name = "Total (Exc. GST):")] 
     public decimal? TotalExcludingGst { get; set; } 

     [Required(ErrorMessage = "Total (Inc. GST) is a required field.")] 
     [Display(Name = "Total (Inc. GST):")] 
     public decimal? TotalIncludingGst { get; set; } 
     public virtual string CreatedByUserName { get; set; } 
     public virtual DateTime CreatedDateTime { get; set; } 
     public virtual string LastModifiedByUserName { get; set; } 
     public virtual DateTime? LastModifiedDateTime { get; set; } 

     // Navigation properties 
     public virtual Area Area { get; set; } 
     public virtual Organisation Organisation { get; set; } 

     public virtual ICollection<InvoiceLine> InvoiceLines { get; set; } 

     #region IValidatableObject Members 

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
     { 
      if ((TotalExcludingGst + (TotalExcludingGst * .15m)) != TotalIncludingGst) { 
       yield return new ValidationResult("The total (exc. Gst) + Gst does not equal the total (inc. Gst)."); 
      } 
     } 

     #endregion 

我想要做的就是確保在INSERT,UPDATE,是的OrgansationInvoiceNumber組合是唯一的。

我考慮的是這樣的:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
      { 
       var repository = new Repository<Invoice>(); 

       if(!repositoy.CheckUnique(Id)) { 
        yield return new ValidationResult("The combination of Organisation and Invoice number is already in use"); 
       } 
      } 

這是不好的做法?要在模型中實例化存儲庫?

有沒有更好的方法?

+0

這有什麼錯捕獲異常,並處理它呢?這樣,您只需在需要時對數據庫進行額外調用即可。 –

+0

你想要你的問題的答案是什麼?更好的方法是在儲存庫之前檢查。或者只是保存,然後處理例如@Jeremy的異常提示。 – mare

+0

但是,這會填充ValidationSummary? – AnonyMouse

回答

3

您的解決方案在多用戶場景下無法正常工作。因爲在檢查ID是否存在以及保存更改之間,可能插入另一條記錄,其編號爲ID

您可以在桌面上創建一個Unique Constraint。這是確保重複項未被創建的安全方法。

當前版本的EF不支持/支持Unique Constraint s。但是,您可以做的是捕獲特定的異常並檢查錯誤消息。然後,如果你正在使用ASP.NET Web表單顯示錯誤

try 
{ 
    //updation logic 
    context.SaveChanges(); 
} 
catch (System.Data.DataException de) 
{ 
    Exception innerException = de; 
    while (innerException.InnerException != null) 
    { 
     innerException = innerException.InnerException; 
    } 

    if (innerException.Message.Contains("Unique_constraint_name")) 
    { 
     ModelState.AddModelError(string.Empty, "Error Message"); 
     return; 
    } 

    ModelState.AddModelError(string.Empty, "Error Message"); 

    return View(); 
} 

,您可以檢查this answer

+0

謝謝,這似乎是最好的選擇。儘管如此,我可以看到微軟正在改變消息文本,導致它不起作用。如果存在某種UniqueConstraintException,會更好。你的方法現在必須做。 – acarlon