Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .Net 5实体框架通用查询_C#_Entity Framework_Generic Programming_.net 5 - Fatal编程技术网

C# .Net 5实体框架通用查询

C# .Net 5实体框架通用查询,c#,entity-framework,generic-programming,.net-5,C#,Entity Framework,Generic Programming,.net 5,由于我是一个懒惰的人,我想为.net FluentValidation实现一个通用的UniqueValidator。目标很简单:有一个验证器,我将模型传递给它,表达式用于获取必须唯一的属性/字段,并运行EFAny查询。这样可以避免每次必须验证DB中某个值的唯一性时都编写哑类 经过几次调整,我找到了一个公平的解决方案,以避免传递和调用预编译的Lambda到EF查询转换器,这当然会导致表达式无法翻译异常 以下是我实施的: public class UniqueValidator : IUniqueV

由于我是一个懒惰的人,我想为.net FluentValidation实现一个通用的UniqueValidator。目标很简单:有一个验证器,我将模型传递给它,表达式用于获取必须唯一的属性/字段,并运行EF
Any
查询。这样可以避免每次必须验证DB中某个值的唯一性时都编写哑类

经过几次调整,我找到了一个公平的解决方案,以避免传递和调用预编译的Lambda到EF查询转换器,这当然会导致
表达式无法翻译
异常

以下是我实施的:

public class UniqueValidator : IUniqueValidator
{
    private ApplicationContext _dbContext;

    public UniqueValidator(ApplicationContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<bool> IsUnique<T>(T model, Expression<Func<T, string>> expression, CancellationToken cancellationToken) where T : class
    {
        // Getting the value to check for unicity:
        Func<T, string> method = expression.Compile(true);
        var value = method(model);

        // For GetDbSet<T>() test purpose, run perfectly:
        bool test = await GetDbSet<T>().OfType<BL.Driver>().AnyAsync(d => d.Email == "any.valid@email.com");


        // Building Linq expression
        var binaryExpression = Expression.Equal(expression.Body, Expression.Constant(value));
        var pe = new ParameterExpression[] { Expression.Parameter(typeof(T)) };

        var anyExpression = Expression.Lambda<Func<T, bool>>(binaryExpression, pe);

        return !(await GetDbSet<T>().AnyAsync(anyExpression));
    }

    private DbSet<T> GetDbSet<T>() where T : class
    {
        return (DbSet<T>)typeof(ApplicationContext)
            .GetProperties()
            .FirstOrDefault(p => p.PropertyType == typeof(DbSet<T>))
            .GetValue(_dbContext);
    }
}
不幸的是,这会引发一个非常麻烦且没有帮助的异常:

System.InvalidOperationException: The LINQ expression 'DbSet<Driver>() .Any(d => d.Email == "any.valid@email.com")' could not be translated...
System.invalidoOperationException:LINQ表达式'DbSet().Any(d=>d.Email==”Any。valid@email.com“”无法翻译。。。
注意:在UniqueValidator实现中,我添加了一行代码来测试异常中描述的同一查询,它运行得非常完美,只是为了消除对查询有效性的任何怀疑

我想问题出在expression.Body的翻译上,但我看不出任何原因,也看不出如何解决这个问题。
任何帮助都将不胜感激。

您必须重新使用表达式的原始参数,或者必须使用表达式替换程序:

var pe = new ParameterExpression[] { Expression.Parameter(typeof(T)) };
改为

var pe = expression.Parameters[0];

您的
GetDbSet
可以替换为
DbContext.Set()
@DavidBrowne-Microsoft确实有助于提高性能,但这并不能解决问题,谢谢。这就是为什么它是一个注释。很久以前,我就不再试图用表达式问题来回答动态LINQ流了。是的,我理解,只是向其他读者和后代提到:)
var pe = expression.Parameters[0];