【问题标题】:Datetime value order constraint日期时间值顺序约束
【发布时间】:2016-06-09 13:40:28
【问题描述】:

我想做一个约束,确保Beginning 小于End。我使用实体框架,据我所知,它不能通过注释来完成。可以用OnModelCreating方法实现吗?

 public class Duty {
        public int Id { get; set; }
        public virtual Employee Employee { get; set; }
        public virtual Store Store { get; set; }
        public DateTime Beginning { get; set; }
        public DateTime End { get; set; }
    }

【问题讨论】:

  • 为什么不在 SQL 中添加这个约束?
  • @M.Suurland 我使用代码优先解决方案,因此任何数据库更新都基于我的 C# 代码。同样,据我所知,有两种基本解决方案 Annotations 或 Fluent API,我认为后者可能会解决它,但我缺乏 Fluent API 部门的知识。
  • 探索以下任何方法有什么运气吗?

标签: c# entity-framework constraints


【解决方案1】:
    public class SomeEntity
    {
        [MustBeLessThanDate(nameof(End))]
        public DateTime Beginning { get; set; }

        public DateTime End { get; set; }
    }

    public class MustBeLessThanDateAttribute : ValidationAttribute
    {
        private readonly string _otherPropertyName;

        public MustBeLessThanDateAttribute(string otherPropertyName)
        {
            _otherPropertyName = otherPropertyName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var containerType = validationContext.ObjectInstance.GetType();

            var field = containerType.GetProperty(_otherPropertyName);

            var otherValue = (DateTime) field.GetValue(validationContext.ObjectInstance, null);

            var thisValue = (DateTime) value;

            return thisValue < otherValue
                ? ValidationResult.Success
                : new ValidationResult("Value is not less than other value");
        }
    }

【讨论】:

  • 这看起来很棒!谢谢!
  • 这个解决方案对我来说看起来是最好的,但是在实体框架映射方面,Darshan Patel 的解决方案有什么优势吗?
  • Darshan 违反了 POCO 的核心原则以及关注点分离。他的代码不可回收。此外,如果您切换 ORM,一些会覆盖 POCO 上的 getter 和 setter。
  • @Timothy Stepanski:我同意并且还要声明您的代码还使用了可重用性,每个开发人员都应该努力实现封装和重用。你的也可以重复使用,并且符合一个原则。另外,您还使用了一个很好的属性。
  • @djangojazz 谢谢,我很感激。
【解决方案2】:

您可以通过从 ValidationAttribute 类派生来使用自定义验证,该类具有您可以覆盖的 IsValid 方法。您可以在 viewModel 中创建此类,然后在结束日期上应用 created 属性。

【讨论】:

    【解决方案3】:

    An answer for the same is here.

    尝试探索FluentValidation

    它使用流畅的接口和 lambda 表达式来构建验证规则。

    从文档中,您可以通过 NuGet 将其包含为 -

    Install-Package FluentValidation
    

    实现一个约束很简单:

    using FluentValidation;
    
    public class CustomerValidator: AbstractValidator<Customer> {
      public CustomerValidator() {
        RuleFor(customer => customer.Surname).NotEmpty();
        RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
        RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
        RuleFor(customer => customer.Address).Length(20, 250);
        RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
      }
    
      private bool BeAValidPostcode(string postcode) {
        // custom postcode validating logic goes here
      }
    }
    
    Customer customer = new Customer();
    CustomerValidator validator = new CustomerValidator();
    ValidationResult results = validator.Validate(customer);
    
    bool validationSucceeded = results.IsValid;
    IList<ValidationFailure> failures = results.Errors;
    

    试试看。 (我没有根据您的需要定制示例,您可能需要深入阅读documentation here。)

    【讨论】:

      【解决方案4】:

      您为什么不在您的财产中使用条件。像这样的......

      public int Id { get; set; }
      public virtual Employee Employee { get; set; }
      public virtual Store Store { get; set; }
      public DateTime Beginning { get; set; }
      
      private DateTime _end;
      public DateTime End {
          get
          {
              return _end;
          }
          set
          {
              if (value < Beginning)
              {
                  throw new Exception("End date can not be less than beginning date.");
              }
              _end = value;
          }
      }
      

      但不要忘记在分配end date之前分配您的beginning date

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-04
        • 2015-05-19
        • 2021-03-27
        • 2014-12-31
        • 2021-10-18
        • 2022-01-14
        • 2012-08-16
        相关资源
        最近更新 更多