EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性

来源:互联网 发布:eia数据公布 时间 编辑:程序博客网 时间:2024/06/05 21:54

创建动态查询


想在项目中实现一个灵活的动态查询类,参考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";




动态查询导航属性


实体关系如图:



如何拼接出 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方法琢磨了老半天才整明白,写在这方便大家吧。执行结果:


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

        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);