zoukankan      html  css  js  c++  java
  • 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中是可以正常运行的:

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

    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.  
    12. 网上的中文资料很少,我对着Expression.Property方法琢磨了老半天才整明白,写在这方便大家吧。 
    13.  
    14. 执行结果: 
    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.   
    12. 网上的中文资料很少,我对着Expression.Property方法琢磨了老半天才整明白,写在这方便大家吧。  
    13.   
    14. 执行结果:  
                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.     string[] propertys = Name.Split('.'); 
    3.     if (source == null) 
    4.     { 
    5.         source = Expression.Property(para, typeof(City).GetProperty(propertys.First())); 
    6.     } 
    7.     else source = Expression.Property(source, propertys.First()); 
    8.     foreach (var item in propertys.Skip(1)) 
    9.     { 
    10.         source = GetProperty(source , para, item); 
    11.     } 
    12.     return source; 
    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); 
  • 相关阅读:
    Android最佳性能实践(二)——分析内存的使用情况
    Android最佳性能实践(一)——合理管理内存
    Java反射机制
    Java基础知识总结之IO流
    Java之IO流详解
    CentOS 6.4安装中文支持
    because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.错误应该怎么解决?
    在asp.net添加引用Microsoft.VisualBasic全过程
    SQL SERVER 2012安装介质
    Microsoft SQL Server附加数据库错误:5123
  • 原文地址:https://www.cnblogs.com/qq260250932/p/4985809.html
Copyright © 2011-2022 走看看