创建动态查询

想在项目中实现一个灵活的动态查询类,参考http://www.cnblogs.com/lyj/archive/2008/03/25/1122157.html和http://www.cnblogs.com/killuakun/archive/2008/08/03/1259389.html后写了一段Demo,发现代码在VS2012 EF4.5中会抛如下异常:

相同的代码在VS2008 EF3.5中是可以正常运行的:

纠结万分后找到解决方法,代码如下:

  1. OscarEntities db = new OscarEntities();
  2. IQueryable<City> cities = db.Citys;
  3. ParameterExpression param = Expression.Parameter(typeof(City), "c");
  4. Expression left = Expression.Property(param, typeof(City).GetProperty("Name"));
  5. Expression right = Expression.Constant("北京市");
  6. Expression filter = Expression.Equal(left, right);
  7. //Expression pred = Expression.Lambda(filter, param);
  8. //Expression expr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(City) },
  9. //    Expression.Constant(cities), pred);
  10. //var result = db.Citys.AsQueryable().Provider.CreateQuery<City>(expr);
  11. var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
  12. list.DataSource = result.ToList();
  13. list.DisplayMember = "Name";
  1. OscarEntities db = new OscarEntities();
  2. IQueryable<City> cities = db.Citys;
  3. ParameterExpression param = Expression.Parameter(typeof(City), "c");
  4. Expression left = Expression.Property(param, typeof(City).GetProperty("Name"));
  5. Expression right = Expression.Constant("北京市");
  6. Expression filter = Expression.Equal(left, right);
  7. //Expression pred = Expression.Lambda(filter, param);
  8. //Expression expr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(City) },
  9. //    Expression.Constant(cities), pred);
  10. //var result = db.Citys.AsQueryable().Provider.CreateQuery<City>(expr);
  11. var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
  12. list.DataSource = result.ToList();
  13. list.DisplayMember = "Name";
            OscarEntities db = new OscarEntities();
IQueryable<City> cities = db.Citys;
ParameterExpression param = Expression.Parameter(typeof(City), "c");
Expression left = Expression.Property(param, typeof(City).GetProperty("Name"));
Expression right = Expression.Constant("北京市");
Expression filter = Expression.Equal(left, right);
//Expression pred = Expression.Lambda(filter, param);
//Expression expr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(City) },
// Expression.Constant(cities), pred);
//var result = db.Citys.AsQueryable().Provider.CreateQuery<City>(expr);
var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
list.DataSource = result.ToList();
list.DisplayMember = "Name";

动态查询导航属性

实体关系如图:

如何拼接出 db.Citys.Where(x => x.Province.Name == "湖南省") 呢?,代码如下:

  1. OscarEntities db = new OscarEntities();
  2. IQueryable<City> cities = db.Citys;
  3. ParameterExpression param = Expression.Parameter(typeof(City), "c");
  4. Expression left = Expression.Property(param, typeof(City).GetProperty("Province")); //先得到导航属性Province
  5. Expression leftproperty = Expression.Property(left, "Name"); //再得到Province.Name
  6. Expression right = Expression.Constant("湖南省");
  7. Expression filter = Expression.Equal(leftproperty, right);
  8. var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
  9. list.DataSource = result.ToList();
  10. list.DisplayMember = "Name";
  11. 网上的中文资料很少,我对着Expression.Property方法琢磨了老半天才整明白,写在这方便大家吧。
  12. 执行结果:
  1. OscarEntities db = new OscarEntities();
  2. IQueryable<City> cities = db.Citys;
  3. ParameterExpression param = Expression.Parameter(typeof(City), "c");
  4. Expression left = Expression.Property(param, typeof(City).GetProperty("Province")); //先得到导航属性Province
  5. Expression leftproperty = Expression.Property(left, "Name"); //再得到Province.Name
  6. Expression right = Expression.Constant("湖南省");
  7. Expression filter = Expression.Equal(leftproperty, right);
  8. var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
  9. list.DataSource = result.ToList();
  10. list.DisplayMember = "Name";
  11. 网上的中文资料很少,我对着Expression.Property方法琢磨了老半天才整明白,写在这方便大家吧。
  12. 执行结果:
            OscarEntities db = new OscarEntities();
IQueryable<City> cities = db.Citys;
ParameterExpression param = Expression.Parameter(typeof(City), "c");
Expression left = Expression.Property(param, typeof(City).GetProperty("Province")); //先得到导航属性Province
Expression leftproperty = Expression.Property(left, "Name"); //再得到Province.Name
Expression right = Expression.Constant("湖南省");
Expression filter = Expression.Equal(leftproperty, right);
var result = db.Citys.Where(Expression.Lambda<Func<City, bool>>(filter, param));
list.DataSource = result.ToList();
list.DisplayMember = "Name"; 网上的中文资料很少,我对着Expression.Property方法琢磨了老半天才整明白,写在这方便大家吧。 执行结果:

再贴上自己项目中用的方法

  1. public Expression GetProperty(Expression source, ParameterExpression para, string Name)
  2. {
  3. string[] propertys = Name.Split('.');
  4. if (source == null)
  5. {
  6. source = Expression.Property(para, typeof(City).GetProperty(propertys.First()));
  7. }
  8. else source = Expression.Property(source, propertys.First());
  9. foreach (var item in propertys.Skip(1))
  10. {
  11. source = GetProperty(source , para, item);
  12. }
  13. return source;
  14. }
  1. public Expression GetProperty(Expression source, ParameterExpression para, string Name)
  2. {
  3. string[] propertys = Name.Split('.');
  4. if (source == null)
  5. {
  6. source = Expression.Property(para, typeof(City).GetProperty(propertys.First()));
  7. }
  8. else source = Expression.Property(source, propertys.First());
  9. foreach (var item in propertys.Skip(1))
  10. {
  11. source = GetProperty(source , para, item);
  12. }
  13. return source;
  14. }
        public Expression GetProperty(Expression source, ParameterExpression para, string Name)
{
string[] propertys = Name.Split('.');
if (source == null)
{
source = Expression.Property(para, typeof(City).GetProperty(propertys.First()));
}
else source = Expression.Property(source, propertys.First());
foreach (var item in propertys.Skip(1))
{
source = GetProperty(source , para, item);
}
return source;
}

使用方法:

  1. ParameterExpression param = Expression.Parameter(typeof(City), "x");
  2. Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
  3. Expression right = Expression.Constant("湖南省");
  4. Expression filter = Expression.Equal(left,right);
  1. ParameterExpression param = Expression.Parameter(typeof(City), "x");
  2. Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
  3. Expression right = Expression.Constant("湖南省");
  4. Expression filter = Expression.Equal(left,right);

EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性的更多相关文章

  1. 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明

    一.首先了解下Entity Framework 自动关联查询: Entity Framework 自动关联查询,有三种方法:Lazy Loading(延迟加载),Eager Loading(预先加载) ...

  2. spring AbstractBeanDefinition创建bean类型是动态代理类的方式

    1.接口 Class<?> resourceClass 2.获取builder BeanDefinitionBuilder builder = BeanDefinitionBuilder. ...

  3. 8.mybatis动态SQL模糊查询 (多参数查询,使用parameterType)

    多参数查询,使用parameterType.实例: 用户User[id, name, age] 1.mysql建表并插入数据 2.Java实体类 public class User { public ...

  4. JAVAEE——Mybatis第二天:输入和输出映射、动态sql、关联查询、Mybatis整合spring、Mybatis逆向工程

    1. 学习计划 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If标签 b) Where标签 c) Sql片段 d) Foreach标签 3.关联查询 a) 一对 ...

  5. MyBatis学习总结(三)——多表关联查询与动态SQL

    在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...

  6. mybatis第二天——动态SQL与关联查询

    大纲摘要: 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If b) Where c) Foreach d) Sql片段 3.关联查询 a) 一对一关联 b) 一 ...

  7. MongoDB动态条件之分页查询

    一.使用QueryByExampleExecutor 1. 继承MongoRepository public interface StudentRepository extends MongoRepo ...

  8. Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询

    在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...

  9. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

随机推荐

  1. Python hasattr() 函数 // python中hasattr()、getattr()、setattr()函数的使用

    http://www.runoob.com/python/python-func-hasattr.html https://www.cnblogs.com/zanjiahaoge666/p/74752 ...

  2. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  3. ElasticSearch 笔记

    ES集群脑裂出现的原因: 1:网络原因 内网一般不会出现此问题,可以监控内网流量状态.外网的网络出现问题的可能性大些. 2:节点负载 主节点即负责管理集群又要存储数据,当访问量大时可能会导致es实例反 ...

  4. POJ 2718 Smallest Difference(最小差)

     Smallest Difference(最小差) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 Given a numb ...

  5. FI CO 常用表

    FI CO 常用表     最近写FICO的报表写得有点多,许多Table记不住,用F1查找又有点费事,不如把表单写下来,以后用到,直接在这上面找得了. 1,账目表主数据  SKA1  SKB1  S ...

  6. 增强 用文本增强修改SAP标准屏幕中的字段名称 属于元素的文本增强

    如果想要改变标准屏幕中的字段名称,如把物料主数据基本数据元素的名字改为我们想要的名字 . 1.首先,事务MM03进入物料主数据的基本数据2视图中,将鼠标光标放在需要更改的字段“页格式”上,然后按F1键 ...

  7. layer 弹出层 回调函数调用 弹出层页面 函数

    1.项目中用到layer 弹出层,定义一个公用的窗口,问题来了窗口弹出来了,如何保存页面上的数据呢?疯狂百度之后,有了结果,赶紧记下. 2.自己定义的公共页面方法: layuiWindow: func ...

  8. C++ 复习要点、面试常见问题总结

    本文总结一下C++面试时常遇到的问题.C++面试中,主要涉及的考点有: 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, n ...

  9. SSH KEY 设置 目录在open ~ 根目录下的.ssh 里面

    当我们从github或者gitlab上clone项目或者参与项目时,需要证明我们的身份.github.gitlab支持使用SSH协议进行免密登录,而SSH协议采用了RSA算法保证了登录的安全性.我们要 ...

  10. 设置本地虚拟域名windows+apache

    C:\WINDOWS\system32\drivers\etc\hosts 在这个文件中 最下面添加. 127.0.0.1   localhost.com 127.0.0.1   cho.com 12 ...