关于Nullable类型转换

qq_24519683 2014-12-15 10:39:23
我通过反射获取一个类型type
然后把一个字符串通过Convert.ChangeType转换 当type为Nullable类型是会报错的
网上查了下 都是当type为Nullable时转为基础基元类型 比如是int?就转为int类型
但是我要创建 Expression表达式
数据库字段是可空的
如果转为int类型 调用Expression.Equal方法会报错
提示不能比较int和int? 有没有什么办法可以解决?
...全文
362 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_24519683 2014-12-15
  • 打赏
  • 举报
回复
引用 2 楼 lc2737 的回复:

Type t = this.GetType();
                    if (t.BaseType.GetGenericTypeDefinition() == typeof (Nullable<>))
                    {

                    }
这个和我网上查的一样啊 如果type是int?就返回int类型 调用 Expression.Equal就会异常 这是代码

  protected IQueryable<T> WhereList<T>(IQueryable<T> query, string name, string value)
        {
            PropertyInfo sortProperty = null;
            if (!string.IsNullOrEmpty(name))
            {
                sortProperty = typeof(T).GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
            }
            if (string.IsNullOrEmpty(value))
                return query;
            if (sortProperty == null)
                throw new Exception("对像上不存在" + sortProperty + "的字段");
            ParameterExpression param = Expression.Parameter(typeof(T), "x");
            Expression left = Expression.Property(param, typeof(T).GetProperty(name));
            Type tp = typeof(T).GetProperty(name).PropertyType;
            //判断类型是否为泛型,因为nullable是泛型类,
            if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果tp为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(tp);
                //将tp转换为nullable对的基础基元类型
                tp = nullableConverter.UnderlyingType;
            }
            Expression right = Expression.Constant(Convert.ChangeType(value, tp));
            Expression filter = Expression.Equal(left, right);
            Expression pred = Expression.Lambda(filter, param);
            Expression expr = Expression.Call(typeof(Queryable), "Where",
                new Type[] { typeof(T) },
                Expression.Constant(query), pred);
            query = query.Provider.CreateQuery<T>(expr);
            return query;
        }
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复

Type t = this.GetType();
                    if (t.BaseType.GetGenericTypeDefinition() == typeof (Nullable<>))
                    {

                    }
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复
关于Nullable和数据库实体之间的转换,参照:http://www.itstrike.cn/Question/CSharp-using-reflection-to-determine-whether-a-type-is-Nullable-access-to-it-at-the-same-time-the-root-type
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复
引用 6 楼 qq_24519683 的回复:
已自行解决

  if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                right = Expression.Constant(Convert.ChangeType(value, tp.GetGenericArguments()[0]));
                right = Expression.Convert(right, tp);
            }
            else
            {
                right = Expression.Constant(Convert.ChangeType(value, tp));
            }
引用点错。。。。

object resultvalue;
            //判断类型是否为泛型,因为nullable是泛型类,
            if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果tp为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(tp);
                resultvalue = nullableConverter.ConvertFromString(value);
            }
            else
            {
                resultvalue = Convert.ChangeType(value, tp);
            }
            Expression right = Expression.Constant(resultvalue);
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复
引用 7 楼 lc2737 的回复:
这样啊,我写的ORM的避免了这个问题,不使用Linq来做。 那你这边这样写就行了。

 object resultvalue;
            //判断类型是否为泛型,因为nullable是泛型类,
            if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果tp为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(tp);
                resultvalue = nullableConverter.ConvertFromString(value);
            }
            else
            {
                resultvalue = Convert.ChangeType(value, tp);
            }

 object resultvalue;
            //判断类型是否为泛型,因为nullable是泛型类,
            if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果tp为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(tp);
                resultvalue = nullableConverter.ConvertFromString(value);
            }
            else
            {
                resultvalue = Convert.ChangeType(value, tp);
            }
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复
这样啊,我写的ORM的避免了这个问题,不使用Linq来做。 那你这边这样写就行了。

 object resultvalue;
            //判断类型是否为泛型,因为nullable是泛型类,
            if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果tp为nullable类,声明一个NullableConverter类,该类提供从Nullable类到基础基元类型的转换
                NullableConverter nullableConverter = new NullableConverter(tp);
                resultvalue = nullableConverter.ConvertFromString(value);
            }
            else
            {
                resultvalue = Convert.ChangeType(value, tp);
            }
qq_24519683 2014-12-15
  • 打赏
  • 举报
回复
已自行解决

  if (tp.IsGenericType &&
                //判断是否为nullable泛型类
                tp.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                right = Expression.Constant(Convert.ChangeType(value, tp.GetGenericArguments()[0]));
                right = Expression.Convert(right, tp);
            }
            else
            {
                right = Expression.Constant(Convert.ChangeType(value, tp));
            }
qq_24519683 2014-12-15
  • 打赏
  • 举报
回复
name 和 value都是前台传过来的集合 可能有多个 都是string类型 我就是想动态生成查询条件 不用每加一个查询条件就多加一个判断 要不然直接list.where就行了 也用不着这个方法了
ajaxfeifei 2014-12-15
  • 打赏
  • 举报
回复
看到你的代码,我清楚了,那我给你的建议是不要这么去做,这样做涉及装箱拆箱,会降低效率。 正确的做法应该是 protected IQueryable<T> WhereList<T>(IQueryable<T> query, string name, T value) 这是一个生成查询条件的方法,在你调用或者别人调用的时候已经知道数据库类型,就没有必要再把传入的值转换为String再传入,直接传同类型的值进来即可。不要把已经的变成未知来处理,这样是不合理的。 ORM不能那个这样去做的,这样做吃力不讨好。

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧