2011-08-22 77 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