gpt4 book ai didi

c# - 如何在运行时设置类型时使用 Queryable.Where?

转载 作者:太空宇宙 更新时间:2023-11-03 12:06:47 25 4
gpt4 key购买 nike

我正在使用 EF6 为应用程序实现搜索/筛选器 UI​​ 的后端。我有代码构建一个与 Queryable.Where 一起使用的表达式,对于给定的 DbSet,DbSet 的类型在运行时确定(DBContext 有很多,它们可能会改变)。如果我通过首先将 Expression 转换为特定类型来作弊,那么对 Where 的调用就可以正常工作。否则,我会收到此错误:

''System.Linq.Queryable.Where(System.Linq.IQueryable, System.Linq.Expressions.Expression>)' 的最佳重载方法匹配有一些无效参数'

我正在努力寻找一种方法来像这样过滤 DbSet,其中在运行时提供基础“表”类型。这里有一个大大简化的代码版本来说明:

    void ProcessFilter(AppDbContext context, NameValueCollection filters, Type tableType)
{
// If tableType == typeof(Organisation), expression is a Expression<Func<Organisation, bool>>
var expression = GetFilterExpression(filters);
var dbset = Set(context, tableType);

dynamic dynamicSet = dbset;

// This fails
var results = Queryable.Where(dynamicSet, expression);
// see https://stackoverflow.com/questions/4285598/iqueryable-non-generic-missing-count-and-skip-it-works-with-iqueryablet

// Suppose tableType == typeof(Organisation)
// This works
var typedExpression = expression as Expression<Func<Organisation, bool>>;
var typedResults = Queryable.Where(dynamicSet, typedExpression);

}

public static IQueryable Set(DbContext context, Type T)
{
// Similar to code in
// https://stackoverflow.com/questions/21533506/find-a-specified-generic-dbset-in-a-dbcontext-dynamically-when-i-have-an-entity
var method = typeof(DbContext).GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "Set" && x.IsGenericMethod).First();

// Build a method with the specific type argument
method = method.MakeGenericMethod(T);

return method.Invoke(context, null) as IQueryable;
}

最佳答案

回答你的具体问题。给定

IQueryable source
LambdaExpression predicate

如何调用静态泛型方法

Queryable.Where<T>(IQueryable<T> source, Expression<Func<T, bool>> predicate)

可以使用 (A) 反射、(B) DLR 动态调度和 (C) Expression.Call 来完成。

您要做的是选项 (B)。然而

var result = Queryable.Where((dynamic)source, predicate);

动态搜索具有 LambdaExpression 类型的第二个参数的方法,这当然会失败。

为了能够动态匹配目标方法,还需要将第二个参数设为dynamic:

var result = Queryable.Where((dynamic)source, (dynamic)predicate); 

上面的等效选项 (C) 实现是:

var result = source.Provider.CreateQuery(Expression.Call(
typeof(Queryable), nameof(Queryable.Where), new[] { source.ElementType },
source.Expression, predicate));

关于c# - 如何在运行时设置类型时使用 Queryable.Where?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54484908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com