asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题
使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到一个问题,如果字段可以为空,提示错误信息:
没有为类型“System.Nullable`1[System.Int32]”和“System.Int32”定义二进制运算符 Equal。
不知到是什么问题,如果字段不为空的话,查询一切正常。希望大家能帮助解决一下。
Find<TEntity>(TEntity obj)方法用途:通过定义实体类,查询符合它的所有记录。
代码
Expression right = Expression.Constant(p.GetValue(obj, null));
Expression left = Expression.Property(param, p.Name);
Expression filter = Expression.Equal(left, right);
Expression left = Expression.Property(param, p.Name);
Expression filter = Expression.Equal(left, right);
主要问题在于 left.Type 是System.Nullable<System.Int32> ,而 right.Type 是System.Int32 。提示错误在:Expression filter = Expression.Equal(left, right);
Expression 的Type为只读。怎样能让两个类型统一,或者能采用其他的方法来避开这个问题。
执行过程:Aritle art=new Article();art.Status=1; var list=db.Find<Article>(art);
Find<TEntity>(TEntity obj) 代码:
1 /// <summary>
2 /// 实现查找
3 /// </summary>
4 /// <typeparam name="TEntity"></typeparam>
5 /// <param name="obj"></param>
6 /// <returns></returns>
7 public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class
8 {
9 //获得所有property的信息
10 PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
11 //构造初始的query
12
13 IQueryable<TEntity> query = this.GetTable<TEntity>().AsQueryable<TEntity>();
14 //遍历每个property
15 foreach (PropertyInfo p in properties)
16 {
17 if (p != null)
18 {
19 Type t = p.PropertyType;
20 //加入object,Binary,和XDocument, 支持sql_variant,imager 和xml等的影射。
21 if (t.IsValueType || t == typeof(string) || t == typeof(System.Byte[])
22 || t == typeof(object) || t == typeof(System.Xml.Linq.XDocument)
23 || t == typeof(System.Data.Linq.Binary))
24 {
25 //如果不为null才算做条件
26
27 if (p.GetValue(obj, null) != null && p.GetValue(obj, null).ToString() != "0001/1/1 0:00:00" && p.GetValue(obj, null).ToString() != "0001-01-01 0:00:00" && p.GetValue(obj, null).ToString() != "0")
28 {
29 if (((ColumnAttribute)(p.GetCustomAttributes(typeof(ColumnAttribute), true)[0])).IsPrimaryKey && Convert.ToInt32(p.GetValue(obj, null)) == 0)
30 {
31
32 }
33 else
34 {
35 ParameterExpression param = Expression.Parameter(typeof(TEntity), "c");
36
37 if (t != typeof(string))
38 {
39 Expression right = Expression.Constant(p.GetValue(obj, null));
40 Expression left = Expression.Property(param, p.Name);
41 Expression filter = Expression.Equal(left, right);
42 Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(filter, param);
43 // Expression SecondCondition = Expression.Call(
44 //Expression.Property(param, p.Name)
45 //, p.PropertyType.GetMethod("Equals")
46 //, Expression.Constant(p.GetValue(obj, null), typeof(string)));
47 // Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(SecondCondition, param);
48 query = query.Where(pred);
49 }
50 else
51 {
52 Expression SecondCondition = Expression.Call(
53 Expression.Property(param, p.Name)
54 , typeof(string).GetMethod("Contains")
55 , Expression.Constant(p.GetValue(obj, null), typeof(string)));
56 Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(SecondCondition, param);
57 query = query.Where(pred);
58 }
59
60 }
61 }
62 }
63 }
64 }
65 return query;
66 }
2 /// 实现查找
3 /// </summary>
4 /// <typeparam name="TEntity"></typeparam>
5 /// <param name="obj"></param>
6 /// <returns></returns>
7 public IQueryable<TEntity> Find<TEntity>(TEntity obj) where TEntity : class
8 {
9 //获得所有property的信息
10 PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
11 //构造初始的query
12
13 IQueryable<TEntity> query = this.GetTable<TEntity>().AsQueryable<TEntity>();
14 //遍历每个property
15 foreach (PropertyInfo p in properties)
16 {
17 if (p != null)
18 {
19 Type t = p.PropertyType;
20 //加入object,Binary,和XDocument, 支持sql_variant,imager 和xml等的影射。
21 if (t.IsValueType || t == typeof(string) || t == typeof(System.Byte[])
22 || t == typeof(object) || t == typeof(System.Xml.Linq.XDocument)
23 || t == typeof(System.Data.Linq.Binary))
24 {
25 //如果不为null才算做条件
26
27 if (p.GetValue(obj, null) != null && p.GetValue(obj, null).ToString() != "0001/1/1 0:00:00" && p.GetValue(obj, null).ToString() != "0001-01-01 0:00:00" && p.GetValue(obj, null).ToString() != "0")
28 {
29 if (((ColumnAttribute)(p.GetCustomAttributes(typeof(ColumnAttribute), true)[0])).IsPrimaryKey && Convert.ToInt32(p.GetValue(obj, null)) == 0)
30 {
31
32 }
33 else
34 {
35 ParameterExpression param = Expression.Parameter(typeof(TEntity), "c");
36
37 if (t != typeof(string))
38 {
39 Expression right = Expression.Constant(p.GetValue(obj, null));
40 Expression left = Expression.Property(param, p.Name);
41 Expression filter = Expression.Equal(left, right);
42 Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(filter, param);
43 // Expression SecondCondition = Expression.Call(
44 //Expression.Property(param, p.Name)
45 //, p.PropertyType.GetMethod("Equals")
46 //, Expression.Constant(p.GetValue(obj, null), typeof(string)));
47 // Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(SecondCondition, param);
48 query = query.Where(pred);
49 }
50 else
51 {
52 Expression SecondCondition = Expression.Call(
53 Expression.Property(param, p.Name)
54 , typeof(string).GetMethod("Contains")
55 , Expression.Constant(p.GetValue(obj, null), typeof(string)));
56 Expression<Func<TEntity, bool>> pred = Expression.Lambda<Func<TEntity, bool>>(SecondCondition, param);
57 query = query.Where(pred);
58 }
59
60 }
61 }
62 }
63 }
64 }
65 return query;
66 }
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------