Entity Framework проверяет уникальность перед вставкой - PullRequest
2 голосов
/ 23 августа 2011

Привет, у меня есть тип 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

Что я хочу сделать, это убедиться, что при обновлении вставки комбинация Organsation и InvoiceNumber уникальна.

Я рассматриваю что-то вроде:

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 Ответ

3 голосов
/ 23 августа 2011

Ваше решение не работает правильно в многопользовательском сценарии.Потому что между проверкой существования ID и сохранением изменений может быть вставлена ​​другая запись с тем же ID.

Вы можете создать Unique Constraint на своей таблице.Это безопасный способ гарантировать, что дубликаты не создаются.

Текущие версии EF не моделируют / не поддерживают Unique Constraint s.Однако вы можете перехватить конкретное исключение и проверить сообщение об ошибке.Затем покажите ошибки

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, вы можете проверить этот ответ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...