EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性
2015-11-22 14:30
423 查看
创建动态查询
想在项目中实现一个灵活的动态查询类,参考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中是可以正常运行的:
纠结万分后找到解决方法,代码如下:
[csharp] view plaincopyprint?
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";
[csharp] view plaincopyprint?
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 == "湖南省") 呢?,代码如下:
[csharp] view plaincopyprint?
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方法琢磨了老半天才整明白,写在这方便大家吧。
执行结果:
[csharp] view plaincopyprint?
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方法琢磨了老半天才整明白,写在这方便大家吧。
执行结果:
再贴上自己项目中用的方法
[csharp] view plaincopyprint?
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;
}
[csharp] view plaincopyprint?
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;
}
使用方法:
[csharp] view plaincopyprint?
ParameterExpression param = Expression.Parameter(typeof(City), "x");
Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
Expression right = Expression.Constant("湖南省");
Expression filter = Expression.Equal(left,right);
[csharp] view plaincopyprint?
ParameterExpression param = Expression.Parameter(typeof(City), "x");
Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
Expression right = Expression.Constant("湖南省");
Expression filter = Expression.Equal(left,right);
想在项目中实现一个灵活的动态查询类,参考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中是可以正常运行的:
纠结万分后找到解决方法,代码如下:
[csharp] view plaincopyprint?
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";
[csharp] view plaincopyprint?
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 == "湖南省") 呢?,代码如下:
[csharp] view plaincopyprint?
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方法琢磨了老半天才整明白,写在这方便大家吧。
执行结果:
[csharp] view plaincopyprint?
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方法琢磨了老半天才整明白,写在这方便大家吧。 执行结果:
再贴上自己项目中用的方法
[csharp] view plaincopyprint?
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;
}
[csharp] view plaincopyprint?
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; }
使用方法:
[csharp] view plaincopyprint?
ParameterExpression param = Expression.Parameter(typeof(City), "x");
Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
Expression right = Expression.Constant("湖南省");
Expression filter = Expression.Equal(left,right);
[csharp] view plaincopyprint?
ParameterExpression param = Expression.Parameter(typeof(City), "x");
Expression left = GetProperty(null, param, "Province.Name"); //得到查询条件属性
Expression right = Expression.Constant("湖南省");
Expression filter = Expression.Equal(left,right);
相关文章推荐
- python3爬虫问题 POST data should be bytes or an iterable of bytes
- Java 类的初始化顺序
- Map KeySet方法
- EF 5.0 帮助类
- 美团点评融资之际与阿里矛盾升级
- 最大K乘积问题
- secureCRT用串口连接Mini2440方法
- 通过Matrix进行二维图形仿射变换
- 【BZOJ】2956: 模积和
- LTE中的CQI RI PMI参数
- 推荐系统(二) —— 利用用户行为数据 —— 基于领域的算法
- EF异常:“System.InvalidOperationException”类型的未经处理的异常在 mscorlib.dll 中发生
- 【BZOJ】2938: [Poi2000]病毒
- linux 创建新用户添加到sudo用户组及基本安装操作等
- open和fopen的区别
- MySQL 表操作
- 寻找最优参数解:最速下降法,牛顿下降法,阻尼牛顿法,拟牛顿法DFP/BFGS
- storyboard(故事版)新手教程 图文详解 3.在故事版上使用scrollview
- Linux命令--scp的使用详解
- FireFly开发之路(四)FireFly配置环境