询问者
linq 动态查询Expression

问题
-
public List<SYS_PROJECTS> SearchAllProjects(SYS_PROJECTS needSearchProj) { List<SYS_PROJECTS> projList = new List<SYS_PROJECTS>(); if (needSearchProj == null) { var sys_ProjectTB = new C_ProjectEntities().SYS_PROJECTS.AsEnumerable(); projList = (from c in sys_ProjectTB select c).ToList(); } else { var projProperties = needSearchProj.GetType().GetMembers().Where(c => c.MemberType == System.Reflection.MemberTypes.Property).Where(c => c.Name!= "PROJECT_ID" && c.Name != "EntityState" && c.Name != "EntityKey").ToList(); //动态查询声明查询参数"b" ParameterExpression b = Expression.Parameter(typeof(SYS_PROJECTS), "b"); //声明被查询的表为SYS_PROJECTS IQueryable<SYS_PROJECTS> queryProj = new C_ProjectEntities().SYS_PROJECTS; foreach(var item in projProperties) { //声明查询的属性 Expression left = Expression.Property(b, typeof(SYS_PROJECTS).GetProperty(item.Name)); //对该属性进行模糊查询 例如:%% Expression right = Expression.Call ( left, typeof(string).GetMethod("IndexOf", new Type[] { typeof(string)}), Expression.Constant(needSearchProj.GetType().GetProperty(item.Name).GetValue(needSearchProj, null)) ); //定义模糊查询的表达式为...indexof>=0 Expression queryPram = Expression.GreaterThanOrEqual(right, Expression.Constant(0)); Expression ifQuery = Expression.IfThenElse ( queryPram, Expression.LessThan(right, Expression.Constant(0)), queryPram ); Expression pred = Expression.Lambda ( ifQuery, b ); //生成Lambda表达式:Where(b=>b.IndexOf("")>=0) Expression expr = Expression.Call ( typeof(Queryable), "Where", new Type[] { typeof(SYS_PROJECTS) }, Expression.Constant(queryProj), pred ); //生成动态查询 IQueryable<SYS_PROJECTS> selectQueryProj = queryProj.Provider.CreateQuery<SYS_PROJECTS>(expr); }
这是我针对一张表的动态模糊查询,当属性有值时执行indexof()>=0没有值时执行indexof()<0的Expression
生成的where lambda表达式类似 where(c=>c.Name.IndexOf("张")>=0?c.Name.IndexOf("张")>=0:c.Name.IndexOf("张")<0);
但是采用动态生成lambda时在
Expression expr = Expression.Call
(
typeof(Queryable), "Where",
new Type[] { typeof(SYS_PROJECTS) },
Expression.Constant(queryProj), pred
);处报出异常: 类型“System.Linq.Queryable”上没有与提供的类型参数和参数兼容的泛型方法“Where”。如果方法是非泛型的,则不应提供类型参数。
请问该怎样解决?
全部回复
-
你好,下面是我从MSDN Library中摘的一段话:
Lambda 用在基于方法的 LINQ 查询中,作为诸如 Where 和 Where 等标准查询运算符方法的参数。
使用基于方法的语法在 Enumerable 类中调用 Where 方法时(像在 LINQ to Objects 和 LINQ to XML 中那样),参数是委托类型 System.Func<T, TResult>。使用 Lambda 表达式创建委托最为方便。例如,当您在 System.Linq.Queryable 类中调用相同的方法时(像在 LINQ to SQL 中那样),则参数类型是 System.Linq.Expressions.Expression<Func>,其中 Func 是包含至多五个输入参数的任何 Func 委托。同样,Lambda 表达式只是一种用于构造表达式目录树的非常简练的方式。尽管事实上通过 Lambda 创建的对象的类型是不同的,但 Lambda 使得 Where 调用看起来类似。
并且根据你的错误信息来看,我想你可以在调用Where() 方法之前试试先调用AsEnumerable()这个方法。因为从http://msdn.microsoft.com/zh-cn/library/bb397687(v=vs.90).aspx这里可以看出Where() 在 Enumerable 类型中可以自由使用,所以可能是因为在System.Linq.Queryable这里面不认识Where()方法的缘故。
希望可以帮到你,
谢谢
Jackie Sun [MSFT]
如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
立刻免费下载 MSDN 论坛好帮手