在EF Linq到实体中使用动态linq

时间:2015-02-25 14:42:32

标签: c# entity-framework linq-to-entities

我正在运行时构建一个Linq.Expressions.Expression,然后我想我会像这样使用它:

Type myTypeVariable = viewModel.typeVariable;
DbContext db = //get entity model for myTypeVariable
Expression myExpression = //build a predicate of myTypeVariable from viewModel
var query = (IQueryable<myType>)db.Set(myTypeVariable);
var results = query.Provider.CreateQuery(myExpression); 

我得到的错误是在.CreateQuery()阶段:“Linq to Entities查询表达式只能从实现IQueryable接口的实例构建。” 我的困惑来自这样一个事实:如果最后一行被它取代,我会得到结果?:results = query.Where(c=>c.ID>0).ToList();

我一直在关注此事:https://msdn.microsoft.com/en-us/library/bb882637.aspx

如何使用我的表达式谓词从我的DbSet中获取结果?

1 个答案:

答案 0 :(得分:1)

通常构建表达式树是很难的部分。 有关详细信息,请参阅Building expression trees

有工具和库可以提供帮助。使用fascades或工具来帮助构建表达式。例如Predicate Builder

您可以将表达式传递给通用存储库以在EF中执行动态Linq。 例如:

public virtual IQueryable<TPoco> GetList(Expression<Func<TPoco, bool>> predicate) {
        return  Context.Set<TPoco>().Where(predicate);
    }

 // a small sample building an expression for Contains string 
 public static Expression<Func<TPoco, bool>> GetContainsPredicate<TPoco>(string propertyName, string containsValue)
    {
        // (tpoco t) => t.propertyName.Contains(value ) as expression 
        var parameterExp = Expression.Parameter(typeof(TPoco), @"t");
        var propertyExp = Expression.Property(parameterExp, propertyName);
        MethodInfo method = typeof(string).GetMethod(@"Contains", new[] { typeof(string) });
        var someValue = Expression.Constant(containsValue, typeof(string));
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);

        return Expression.Lambda<Func<TPoco, bool>>(containsMethodExp, parameterExp);
    }

用法:

 var  someExp = MyTool.GetContainsPredicate("FIELDNAME","SomeString");
 var resultQueryable = myRepOfTpoco.GetList(someExp )  ;
相关问题