EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性
创建动态查询
想在项目中实现一个灵活的动态查询类,参考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中是可以正常运行的:

纠结万分后找到解决方法,代码如下:
- 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";
- 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";
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 == "湖南省") 呢?,代码如下:
- 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方法琢磨了老半天才整明白,写在这方便大家吧。
- 执行结果:
- 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方法琢磨了老半天才整明白,写在这方便大家吧。
- 执行结果:
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方法琢磨了老半天才整明白,写在这方便大家吧。 执行结果:

再贴上自己项目中用的方法
- 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;
- }
- 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;
- }
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;
}
使用方法:
- ParameterExpression param = Expression.Parameter(typeof(City), "x");
- Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
- Expression right = Expression.Constant("湖南省");
- Expression filter = Expression.Equal(left,right);
- ParameterExpression param = Expression.Parameter(typeof(City), "x");
- Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
- Expression right = Expression.Constant("湖南省");
- Expression filter = Expression.Equal(left,right);
EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性的更多相关文章
- 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明
一.首先了解下Entity Framework 自动关联查询: Entity Framework 自动关联查询,有三种方法:Lazy Loading(延迟加载),Eager Loading(预先加载) ...
- spring AbstractBeanDefinition创建bean类型是动态代理类的方式
1.接口 Class<?> resourceClass 2.获取builder BeanDefinitionBuilder builder = BeanDefinitionBuilder. ...
- 8.mybatis动态SQL模糊查询 (多参数查询,使用parameterType)
多参数查询,使用parameterType.实例: 用户User[id, name, age] 1.mysql建表并插入数据 2.Java实体类 public class User { public ...
- JAVAEE——Mybatis第二天:输入和输出映射、动态sql、关联查询、Mybatis整合spring、Mybatis逆向工程
1. 学习计划 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If标签 b) Where标签 c) Sql片段 d) Foreach标签 3.关联查询 a) 一对 ...
- MyBatis学习总结(三)——多表关联查询与动态SQL
在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...
- mybatis第二天——动态SQL与关联查询
大纲摘要: 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If b) Where c) Foreach d) Sql片段 3.关联查询 a) 一对一关联 b) 一 ...
- MongoDB动态条件之分页查询
一.使用QueryByExampleExecutor 1. 继承MongoRepository public interface StudentRepository extends MongoRepo ...
- Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询
在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...
随机推荐
- 【python35.2--图形用户界面EasyGui】
一.猜字游戏 #猜字游戏(从1到10) import easygui as g import random g.msgbox('欢迎进入探险之路!') screct = random.randint( ...
- 网络 --- 3 socket模块 粘包
一 .socket 模块参数及方法 二.缓冲区 三.粘包 1.两种粘包现象 ①连续的小包可能会被优化算法给组合到一起进行发送 ②第一次如果发送的数据大小2000B接收端一次性接受大小为1024, 这就 ...
- 数组中的元素 增加push用法 unshift() 方法 和减少pop() 方法 shift() 和其他位置增删 splice() 方法 join() 方法 reverse() 方法 sort() 方法
push用法 push 英 [pʊʃ] 美 [pʊʃ] vt. 推,推动; vt. 按; 推动,增加; 对…施加压力,逼迫; 说服; n. 推,决心; 大规模攻势; 矢志的追求 定义和用法 push( ...
- aria2的下载配置
aria2的命令行命令是: aria2c 一种方式: aria2c "http://host/file.zip" 如同wget 第二种方式: rpc server方式:
- loj SDOI2017数字表格
目录 太才了 注意,错误 代码 太才了 \(\prod \limits_{i=1}^{n}\prod\limits_{j=1}^{m}f[gcd(i,j)]\) \(\prod\limits_{k=1 ...
- HDU 4632 Palindrome subsequence & FJUT3681 回文子序列种类数(回文子序列个数/回文子序列种数 容斥 + 区间DP)题解
题意1:问你一个串有几个不连续子序列(相同字母不同位置视为两个) 题意2:问你一个串有几种不连续子序列(相同字母不同位置视为一个,空串视为一个子序列) 思路1:由容斥可知当两个边界字母相同时 dp[i ...
- Bytom设计结构解读
一.引文 设计Bytom 数据结构,组合了许多技术点,如 patricia tree,utxo, bvm, account model,protobuf,sql,memcache 等.本文会对一些技术 ...
- K8S 安装笔记
1. 准备CentOS7环境 #关闭防火墙 # systemctl disable firewalld # systemctl stop firewalld #安装etcd, kubernetes(会 ...
- 51nod P1305 Pairwise Sum and Divide ——思路题
久しぶり! 发现的一道有意思的题,想了半天都没有找到规律,结果竟然是思路题..(在大佬题解的帮助下) 原题戳>>https://www.51nod.com/onlineJudge/ques ...
- PowerDesigner使用方法入门学习
[转载:https://www.cnblogs.com/biehongli/p/6025954.html] 1:入门级使用PowerDesigner软件创建数据库(直接上图怎么创建,其他的概念知识可自 ...