我的WCF数据服务(三)胜利

这个问题解决起来还颇费了一些周章。在搜索解决方案的时候,发现了这篇文章:http://blog.csdn.net/heshengfen123/article/details/17301079
和我遇到了同样的问题。作者使用了 Dynamic Expression API 这个组件解决了问题,我也按照文章上说的下载了这个组件,放到了项目里,于是代码变成了这样:

int i = 3,rc;
var q = System.Linq.Dynamic.DynamicExpression.ParseLambda<XXX, bool>("id>@0", i);
var l = BLL.XXX.GetList(30,1,q,x=>x.id,true,out rc);

运行又可以了,但是当我需要按字符串查询的时候,又不行了,我本来要这样:

int rc;
string s = "中";
var l = BLL.XXX.GetList(30,1,x=>x.name.Contains(s),x=>x.id,true,out rc);
可是 System.Linq.Dynamic.DynamicExpression.ParseLambda<XXX, bool>("name.Contains(\" + s + "\""); 

这样会报错。
我不明白是怎么回事,于是研究起 Dynamic Expression API 这个组件的源代码,发现只实现了 = < > 等这样符号的运算。这样的话基本上在生产环境是没法用的。不过我在研究的过程中学到了不少 Expression 相关的知识,然后就想想有什么样的解决办法。我想,既然他们能动态的生成一个表达式,那我也能啊,我生成完再组合起来,也一样用啊。于是我照着他们的代码,自己写了一些建立表达式树的辅助方法。

public static Expression<Func<T, bool>> ToExpressionContainsMe<T>(this string s, Expression<Func<T, string>> keySelector)
        {
            MethodCallExpression met = Expression.Call(keySelector.Body, typeof(string).GetMethod("Contains"), Expression.Constant(s));
            Expression<Func<T, bool>> lamb = Expression.Lambda<Func<T, bool>>(met, keySelector.Parameters);
            return lamb;
        }

public static Expression<Func<T, bool>> ToExpressionEqual<T>(this int i, Expression<Func<T,int>> keySelector)
        {
            return Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Constant(i), keySelector.Body), keySelector.Parameters);
        }

这里举两个例子,别的都是大同小异的。又从网上抄了段能 And Or 组合表达式的代码,我不放这了,请自己去搜。
于是代码成了这样:

int i=3,j=100,rc;
Expression<Func<Model.XXX,bool>> q = i.ToExpressionGreaterThanMe(x=>x.id);
q = q.And(j.ToExpressionLessThanMe(x=>x.id));
string s = "中";
q = q.And(s.ToExpressionContainsMe(x=>x.name));
var l = BLL.XXX.GetList(30,1,q,x=>x.id,true,out rc);

这样就成功了,完全可以用到生产环境了。

猜你喜欢

转载自blog.csdn.net/zl33842902/article/details/52247752