zoukankan      html  css  js  c++  java
  • ADO.NET EF 4中 query.Where().Where()和动态组合lambda实现组合查询的不同。

    我记得在ADO.NET EF 1.0中,如果用query.Where().Where()写法生成的SQL比较弱智,就是嵌套一层一层的子查询,那么再VS2010有没有改进捏???我做个例子检验一下。

    新建一个ASP.NET MVC2的工程,数据库就用SQL2000就有的Northwind,只用一个Customers表。

    直接在HomeController上加Query方法,默认情况下显示全部。

    代码

            [HttpGet]
            
    public ActionResult Query()
            {
                
    using (var context = new NorthwindEntities())
                {
                    
    return this.View(context.Customers.ToList<Customers>());
                }
            }

    查询表单代码,如果textbox为空,就代表放弃这个条件。

    代码

        <% using (this.Html.BeginForm())
           { 
    %>

            
    <fieldset>
                    
    <legend>搜索</legend>
                    
                    
    <div class="editor-label">
                        城市
                    
    </div>
                    
    <div class="editor-field">
                        
    <%: Html.TextBox("city",this.Request["city"]) %>
                    
    </div>
                    
    <div class="editor-label">
                        公司
                    
    </div>
                    
    <div class="editor-field">
                        
    <%: Html.TextBox("company", this.Request["company"])%>
                    
    </div>
                    
    <div class="editor-label">
                        联系人
                    
    </div>
                    
    <div class="editor-field">
                        
    <%: Html.TextBox("contactName", this.Request["contactName"])%>
                    
    </div>
                    
    <p>
                        
    <input type="submit" value="搜索" />
                    
    </p>
            
    </fieldset>

        
    <% } %>

    使用query.Where().Where()实现的代码

    代码
            [HttpPost]
            
    public ActionResult Query(string city, string company, string contactName)
            {
                
    using (var context = new NorthwindEntities())
                {
                    var query 
    = context.Customers.AsQueryable<Customers>();
                    
    if (!string.IsNullOrEmpty(city))
                    {
                        query 
    = query.Where<Customers>(c => c.City == city);
                    }
                    
    if (!string.IsNullOrEmpty(company))
                    {
                        query 
    = query.Where<Customers>(c => c.CompanyName.Contains(company));
                    }
                    
    if (!string.IsNullOrEmpty(contactName))
                    {
                        query 
    = query.Where<Customers>(c => c.ContactName.Contains(contactName));
                    }
                    
    return this.View(query.ToList<Customers>());
                }
            }

    动态使用表达式树的代码

    代码
            [HttpPost]
            
    public ActionResult Query(string city, string company,string contactName)
            {
                
    using (var context = new NorthwindEntities())
                {
                    
                    var parameter 
    = Expression.Parameter(typeof(Customers));
                    var type 
    = typeof(Customers);
                    Expression expr 
    = Expression.Constant(true);
                    var methodInfo 
    = typeof(string).GetMethod("Contains"new Type[] { typeof(string) });
                    
    if (!string.IsNullOrEmpty(city))
                    {
                        expr 
    = Expression.And(expr,
                            Expression.Equal(Expression.Property(parameter, 
    "City"), Expression.Constant(city)));
                    }
                    
    if (!string.IsNullOrEmpty(company))
                    {
                        expr 
    = Expression.And(expr,
                            Expression.Call(Expression.Property(parameter, 
    "CompanyName"), methodInfo, Expression.Constant(company)));
                    }
                    
    if (!string.IsNullOrEmpty(contactName))
                    {
                        expr 
    = Expression.And(expr,
                            Expression.Call(Expression.Property(parameter, 
    "ContactName"), methodInfo, Expression.Constant(contactName)));
                    }

                    var lambda 
    = Expression.Lambda<Func<Customers, bool>>(expr, parameter);
                    
    return this.View(context.Customers.Where<Customers>(lambda).ToList<Customers>());
                }
            }

     

    效果都是一样滴

     那个这两个方法生成的SQL有什么不同捏?用SQL SERVER Profiler监视的query.Where().Where()的结果发现,在ADO.NET EF 4已经不在嵌套的子查询,已经智能滴合并了,但是用了sp_executesql这个存储过程。

    代码

    exec sp_executesql N'SELECT 
    [Extent1].[CustomerID] AS [CustomerID], 
    [Extent1].[CompanyName] AS [CompanyName], 
    [Extent1].[ContactName] AS [ContactName], 
    [Extent1].[ContactTitle] AS [ContactTitle], 
    [Extent1].[Address] AS [Address], 
    [Extent1].[City] AS [City], 
    [Extent1].[Region] AS [Region], 
    [Extent1].[PostalCode] AS [PostalCode], 
    [Extent1].[Country] AS [Country], 
    [Extent1].[Phone] AS [Phone], 
    [Extent1].[Fax] AS [Fax]
    FROM [dbo].[Customers] AS [Extent1]
    WHERE ([Extent1].[City] = @p__linq__0) AND ([Extent1].[CompanyName] LIKE @p__linq__1 ESCAPE N
    ''~'') AND ([Extent1].[ContactName] LIKE @p__linq__2 ESCAPE N''~'')',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000),@p__linq__2 nvarchar(4000)',@p__linq__0=N'Berlin',@p__linq__1=N'%Futterkiste%',@p__linq__2=N'%Anders%'

    动态组合表达式确没用存储过程,直接就一条SQL语句

    代码

    SELECT 
    [Extent1].[CustomerID] AS [CustomerID]
    [Extent1].[CompanyName] AS [CompanyName]
    [Extent1].[ContactName] AS [ContactName]
    [Extent1].[ContactTitle] AS [ContactTitle]
    [Extent1].[Address] AS [Address]
    [Extent1].[City] AS [City]
    [Extent1].[Region] AS [Region]
    [Extent1].[PostalCode] AS [PostalCode]
    [Extent1].[Country] AS [Country]
    [Extent1].[Phone] AS [Phone]
    [Extent1].[Fax] AS [Fax]
    FROM [dbo].[Customers] AS [Extent1]
    WHERE (N'Berlin' = [Extent1].[City]AND ([Extent1].[CompanyName] LIKE N'%Alfreds%'AND ([Extent1].[ContactName] LIKE N'%Maria%')

    看来ADO.NET EF对于两种方式生成的SQL还是区别对待的,如果只有一条WHERE语句,那么直接将Lambda转换为SQL,如果是多条WHERE,还能优化SQL。所以如果是动态的AND AND AND查询,两种方式差不多,我觉得Where().Where()的方式可读性更好,如果是比较复杂的查询,比如带OR的,还要用动态组合表达式树的方式。

  • 相关阅读:
    elasticsearch 启动
    经纬度解析API
    http://t.cn/xxxxx的短链接如何生成?
    IIS+PHP上传文件大小限制和上传时间限制,iis7和iis8上传文件大小限制和上传时间限制
    WIN2003+IIS6环境SSL证书的安装
    如何创建文件名前带点的文件夹,文件夹名字带点
    解决MYSQL的错误:Got a packet bigger than 'max_allowed_packet' bytes
    php 设置临时内存和超时设置脚本最大执行时间
    谷歌地图 API 开发之获取坐标以及街道详情
    隐藏 google 地图 Logo 隐藏 百度 地图 Logo
  • 原文地址:https://www.cnblogs.com/subwayline13/p/1810246.html
Copyright © 2011-2022 走看看