首页 新闻 会员 周边

关于Nh LINQ 扩展 自定义 lambda表达式的问题

0
悬赏园豆:50 [已解决问题] 解决于 2012-11-19 13:06
public static IQueryable<TSource> TestExtebsion<TSource>(this IQueryable<TSource> source)
{
Type _type = typeof(TSource);
ParameterExpression parm = Expression.Parameter(_type, "p");
var body1 = Expression.Equal(Expression.Property(parm, _type.GetProperty("CompanyId")),
Expression.Constant(1));

var body2 = Expression.Call(Expression.Property(parm, _type.GetProperty("CompanyName"))
, typeof(string).GetMethod("Contains"), Expression.Constant("宁夏"));

Expression bodys = Expression.Or(body1, body2);

var expression = (Expression<Func<TSource, bool>>)Expression.Lambda<Func<TSource, bool>>(bodys, parm);
return source.Where(expression);
}

上面是自定义的一个扩展方法 目的是 后期自己构造一些 弱类型的查询条件  通过自己组装成为各种查询条件

 

 var _query = Session.Query<Company>()
                              .Select(p => new { p.CompanyId, p.CompanyName, p.CreateDate, p.Assets })
                              .TestExtebsion()
                              .ToList();

 

这个是 NH 访问时调用上面的 扩展方法

问题来了

如果是 

var expression = (Expression<Func<TSource, bool>>)Expression.Lambda<Func<TSource, bool>>(body1, parm);
单独用一个表达式 就没有任何问题
但是 如果像 第一个代码片段中那样 把 body1 和 body2 用 OR 或者 AND 拼接起来的话 (生成表达式如下)
p => ((p.CompanyId == 1) Or p.CompanyName.Contains("宁夏"))
就会报以下异常,反正就是不能 组合多个 表达式

无法将类型为“NHibernate.Hql.Ast.HqlBitwiseOr”的对象强制转换为类型“NHibernate.Hql.Ast.HqlBooleanExpression”。

 

求救


NH 是3.1


一只老菜鸟。的主页 一只老菜鸟。 | 菜鸟二级 | 园豆:224
提问于:2012-11-18 23:50
< >
分享
最佳答案
1
Expression bodys = Expression.Or(body1, body2);

注意Expression.Or 返回的是body1和body2的 bitwise or结果: body1 | body2, 如果想计算 body1 || body2,你应该使用Expression.OrElse

收获园豆:30
水牛刀刀 | 大侠五级 |园豆:6350 | 2012-11-19 00:58
其他回答(2)
0
public static IQueryable<TSource> TestExtebsion<TSource>(this IQueryable<TSource> source)
换成
public static IQueryable<T> TestExtebsion<S>(this IQueryable<T> source)
<Func<TSource, bool>换成
<Func<TSource, S>
收获园豆:5
王大湿 | 园豆:457 (菜鸟二级) | 2012-11-19 12:13

http://www.cnblogs.com/hun_dan/archive/2012/10/23/2735255.html

支持(0) 反对(0) 王大湿 | 园豆:457 (菜鸟二级) | 2012-11-19 12:14
0
public static string RouteMap(Expression expression)
        {
            string sb = string.Empty;
            if (expression is BinaryExpression)
            {
                BinaryExpression be = ((BinaryExpression)expression);
                return Provider.BinaryProvider(be.Left, be.Right, be.NodeType);
            }
            else if (expression is MemberExpression)
            {
                MemberExpression me = ((MemberExpression)expression);
                return me.Member.Name;
            }
            else if (expression is NewArrayExpression)
            {
                NewArrayExpression ae = ((NewArrayExpression)expression);
                StringBuilder tmpstr = new StringBuilder();
                foreach (Expression ex in ae.Expressions)
                {
                    tmpstr.Append(RouteMap(ex));
                    tmpstr.Append(",");
                }
                return tmpstr.ToString(0, tmpstr.Length - 1);
            }
            else if (expression is MethodCallExpression)
            {
                MethodCallExpression mce = (MethodCallExpression)expression;
                if (mce.Method.Name == "Like")
                    return string.Format("({0} like {1})", RouteMap(mce.Arguments[0]), RouteMap(mce.Arguments[1]));
                else if (mce.Method.Name == "NotLike")
                    return string.Format("({0} Not like {1})", RouteMap(mce.Arguments[0]), RouteMap(mce.Arguments[1]));
                else if (mce.Method.Name == "In")
                    return string.Format("{0} In ({1})", RouteMap(mce.Arguments[0]), RouteMap(mce.Arguments[1]));
                else if (mce.Method.Name == "NotIn")
                    return string.Format("{0} Not In ({1})", RouteMap(mce.Arguments[0]), RouteMap(mce.Arguments[1]));

            }
            else if (expression is ConstantExpression)
            {
                ConstantExpression ce = ((ConstantExpression)expression);
                if (ce.Value == null)
                    return "null";
                else if (ce.Value is ValueType)
                    return ce.Value.ToString();
                else if (ce.Value is string || ce.Value is DateTime || ce.Value is char)
                    return string.Format("'{0}'", ce.Value.ToString());
            }
            else if (expression is UnaryExpression)
            {
                UnaryExpression ue = ((UnaryExpression)expression);
                return RouteMap(ue.Operand);
            }
            return string.Empty;
        }
收获园豆:15
贺臣 | 园豆:307 (菜鸟二级) | 2012-11-19 12:42
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册