【问题标题】:How to Validate against Entity Framework Core Field Properties with Fluent Validation如何使用 Fluent Validation 针对 Entity Framework Core 字段属性进行验证
【发布时间】:2020-11-06 20:46:29
【问题描述】:

我正在尝试针对 Entity Framework Core 中的 .HasMaxLength 属性进行验证。

这是一个示例模型构建器方法:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
             {
              modelBuilder.Entity<Address>(entity =>
                 {
              
                  entity.Property(e => e.AddressEmail)
                .IsRequired()
                .HasMaxLength(255)
                .IsUnicode(false)
                .HasDefaultValueSql("('')");

使用我的上下文,我可以像这样找到最大长度:

  dbContext.Model.FindEntityType(typeof(Address)).FindProperty("AddressEmail").GetMaxLength()

使用 Fluent Validation,我可以做到这一点:

  RuleFor(Address => Address.AddressEmail).NotNull().MaximumLength(255);

这样可以,但是当我更改数据库结构时,我必须更新我的验证器。

我试图弄清楚如何从实体框架 MaxLength 属性驱动我的 Fluent Validation 规则

任何帮助将不胜感激。

**** 引入 dbcontext 的部分工作方式,但我仍在努力获取规则:

 public AddressValidator(DbContext dbContext)
      {
        Microsoft.EntityFrameworkCore.Metadata.IEntityType et = dbContext.Model.FindEntityType(typeof(Address));

        foreach (var Property in et.GetProperties())
        {
            var maxLength = Property.GetMaxLength();
  ---->>>>> RuleFor(x =>x.{PropertyName})    Invalid but this is the idea
        }
            

【问题讨论】:

  • 考虑使用数据注释验证。在这种情况下,您可以将一些带有自定义验证的属性放到部分类中。
  • 谢谢,@Sergey - 我开始使用 Data Annotation,但我的验证太复杂了,而且我不断收到关于库版本的无法克服的错误。这是个好主意 - 它只是不适合我的情况。

标签: c# entity-framework entity-framework-core fluentvalidation


【解决方案1】:

您可以使用之前提供的代码将您的数据库上下文注入验证器。不确定是否有适配器自动完成

class MyClassValidator : AbstractValidator<MyClass>
{
    public MyClassValidator(MyDbContext dbContext)
    {
        var maxLength = dbContext.Model.FindEntityType(typeof(MyClass))
            .FindProperty(nameof(MyClass.Data)).GetMaxLength();

        RuleFor(x => x.Data)
            .MaximumLength(maxLength.Value);
    }
}

更新

使用表达式的版本

class MyClassValidator : AbstractValidator<MyClass>
{
    public MyClassValidator(MyDbContext dbContext)
    {
        var entityType = dbContext.Model.FindEntityType(typeof(MyClass));

        foreach (var property in typeof(MyClass).GetProperties()
            .Where(x => x.PropertyType == typeof(string)))
        {
            var maxLength = entityType
                .FindProperty(property.Name)
                .GetMaxLength();

            if (maxLength.HasValue) 
            {
                var parameter = Expression.Parameter(typeof(MyClass));
                var memberExpression = Expression.Property(parameter, property.Name);
                var lambdaExpression = Expression.Lambda<Func<MyClass, string>>(memberExpression, parameter);

                RuleFor(lambdaExpression)
                    .MaximumLength(maxLength.Value);
            }
        }

    }
}

【讨论】:

  • 感谢您的回复。它让我很顺利。我将您的想法添加到我的帖子中的代码中。问题出在 RuleFor x.Data 我无法插入类型类型。我希望你能看看它,让我知道任何想法。谢谢。
  • 天啊——叶戈尔——你太棒了!它奏效了,我一直在寻找关于如何做类似 lambda 表达式的事情。我会在你的另一篇文章中为你投票,因为我在这里只有一个投票。
猜你喜欢
  • 1970-01-01
  • 2015-11-05
  • 2011-12-26
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多