在非泛型DbSet上应用动态构建的表达式

本文关键字:动态 构建 表达式 应用 泛型 DbSet | 更新日期: 2023-09-27 18:03:02

我有以下场景:

  • 我在编译时有一个未知的DbSet,我通过它的类型得到它,如:

    DbSet entities = _repository.Context.Set(myType)
    
  • 我有一个给定类型的动态构建表达式,

    Expression myFilter;//构建为myType的表达式,在运行时构建

如何在entities上应用myFilter,以过滤出基于myFilter的实体?

在非泛型DbSet上应用动态构建的表达式

下面的代码可能会对您有所帮助:它最终创建了一个myType的IQueryable,它实际上表示类似的东西SELECT * FROM YourMappedTable WHERE Id = 1但是,当然,不是使用我为演示目的而构建的表达式,你可以使用你的表达式。

class Program
{
    static void Main(string[] args)
    {
        using (var x = new DB01Entities ())
        {
            Type myType = typeof(Angajati);
            var setMethod = typeof(DB01Entities).GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).Where (a => a.Name == "Set" && a.IsGenericMethod).First ().GetGenericMethodDefinition ();
            var mySet = setMethod.MakeGenericMethod(myType);
            var realSet = mySet.Invoke(x, null);
            var param1 = Expression.Parameter(myType, "param1");
            var propertyExpresion = Expression.Property(param1, "Id");
            var idExpresssion = Expression.Constant(1);
            var body = Expression.Equal(propertyExpresion, idExpresssion);
            var lambda = Expression.Lambda(body, param1);
            var genericTypeCaster = typeof(Program).GetMethod("Caster", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetGenericMethodDefinition();
            var effectiveMethod = genericTypeCaster.MakeGenericMethod(myType);
            var filteredQueryable = effectiveMethod.Invoke(null, new Object[] {realSet, lambda });
        }
    }
    private static IQueryable<T> Caster <T> (DbSet<T> theSet, Expression whereCondition) where T : class
    {
        return theSet.Where(whereCondition as Expression<Func<T, bool>>);
    }
}

所以上面的"lambda"变量相当于你的"myFilter"。它必须在运行时

Expression<Func<YourType, bool>>.

mySet是你的"实体"DbSet。编码快乐!