实体框架在插入之前检查唯一性

时间:2011-08-22 21:46:24

标签: asp.net-mvc entity-framework

您好我有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

我想要做的是确保在插入更新时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");
                }
            }

这是不好的做法吗?要在模型中实例化存储库吗?

有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

您的解决方案在多用户方案中无法正常运行。因为在检查是否存在ID和保存更改之间,可能会使用相同的ID插入另一条记录。

您可以在桌面上创建Unique Constraint。这是确保不创建重复项的安全方法。

当前版本的EF不会建模/支持Unique Constraint。但是,您可以执行的操作是捕获特定异常并检查错误消息。然后显示错误

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();
}

如果您使用的是ASP.NET Web表单,可以查看this answer