开发者

Entity Framework check for uniqueness before insert

Hi I have an Invoice type like:

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

What I want to do is make sure on insert update that the combination of Organsation and InvoiceNumber is unique.

I'm considering something like:

public IEnumerable<ValidationResult> Validate(Valid开发者_如何学GoationContext 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");
                }
            }

Is this bad practise? To be instantiating the repository inside the model?

Is there a better way?


Your solution is not work correctly in a multi user scenario. Because between checking whether an ID exists and saving changes another record maybe inserted with that same ID.

You can create a Unique Constraint on your table. This is the safe way to ensure duplicates are not created.

Current versions of EF does not model/support Unique Constraints. However what you can do is catch the specific exception and check the error message. Then show the errors

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

If you are using ASP.NET Web forms you can check this answer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜