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(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");
}
}
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
IDexists and saving changes another record maybe inserted with that sameID.You can create a
Unique Constrainton 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 errorsIf you are using ASP.NET Web forms you can check this answer