• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別

    發布: 2008-5-07 13:46 | 作者: 網絡轉載 | 來源: 本站原創 | 查看: 185次 | 進入軟件測試論壇討論

    領測軟件測試網

     

    我們再來測試一下

    Northwind db = new Northwind(); db.Log = Console.Out; Customer cu = new Customer { City = "London", Country = "UK" }; var q0 = db.Customers.Find(cu).ToList(); var q1 = db.Customers.OrderBy(c=>c.Country).Find(cu, false).ToList(); var q2 = Extension.Find(db.Customers.OrderBy(c => c.CustomerID), cu).ToList();

      大家可以看到,它們和系統定義方法一樣使用,可以接在任何滿足條件的語句后面。第三個例子直接就用的static方法的形式。從第三個例子,我們可以看出,extension methods和static methods差別其實不大。

      它們生成的sql

    SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address ], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] FROM [dbo].[Customers] AS [t0] WHERE ([t0].[City] = @p0) AND ([t0].[Country] = @p1) -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London] -- @p1: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [UK] SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address ], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] FROM [dbo].[Customers] AS [t0] WHERE ([t0].[City] = @p0) OR ([t0].[Country] = @p1) ORDER BY [t0].[Country] -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London] -- @p1: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [UK] SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address ], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] FROM [dbo].[Customers] AS [t0] WHERE ([t0].[City] = @p0) AND ([t0].[Country] = @p1) ORDER BY [t0].[CustomerID] -- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London] -- @p1: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [UK]

      2,限定字段在某集合中
      這有點像in操作。比如where city in ('London', 'BeiJing') 也可以寫成 where city = 'London' or city = 'BeiJing'。既然談到or條件的動態構造了,那就也來構造下這個吧?瓷先ビ悬c多此一舉。但是,至少是個很好的學習機會。這個和上面不同的是,它條件字段是唯一的,變化的是該字段的值。那用一string將字段名成傳入,并用一集合將字段值傳入函數。
      該函數完整的定義入下:

    public static IQueryable<TEntity> WhereOr<TEntity, OrType>(this IQueryable<TEntity> source, string propertyName, IEnumerable<OrType> values) { if (source == null) throw new ArgumentNullException("Source can't be null!!"); ParameterExpression param = Expression.Parameter(typeof(TEntity), "p"); Expression left = Expression.Property(param, propertyName); Expression condition = null; foreach (OrType value in values) { Expression filter = Expression.Equal(left, Expression.Constant(value)); if (condition == null) condition = filter; else condition = Expression.Or(condition,filter); } if (condition != null) return source.Where((Expression<Func<TEntity, bool>>)Expression.Lambda(condition, param)); return source; }

      使用時,
      var q3 = db.Customers.WhereOr("City", new List<string> { "London", "BeiJing" }).ToList();
      并不在多做解釋。

      3, CLRSQL在某些細節上的差別
      在上文中,有一朋友提出,其值不為null才做為條件,讓函數有局限性。既然提了,那筆者就再引申下。CLR與SQL中,對待null值是不同的。CLR認為兩個null值是相等的,而SQL并不這么認為。比如,下面的條件就是成立的。
      if (null == null)
      throw new Exception("CLR treat Null is the same!!");
      但在Sql中只能判斷是不是null值,而不能對兩個字段的null值直接比較。
      比如下面的語句
      var q6 = db.Employees.Where(c => c.Region == null).ToList();
      翻譯為:

    SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0]. [TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City ], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Ext ension], [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath] FROM [dbo].[Employees] AS [t0] WHERE [t0].[Region] IS NULL

      Linq To Sql是通過Ado.Net于Sql打交道的。也就是說Linq To Sql是建立在CLR基礎上的。這點細小的差別讓Linq To Sql不知道該與誰保持平行。 Where條件中,有 == 和Equal兩個方法,它們在Linq To Sql中是不一樣的。Equal認為null是相等的。但是sql又不能用=來判斷,所以Equal方法翻譯的sql語句就有些長。請大家自己仔細比較下面兩個語句的sql差別

    var q5 = (from e in db.Employees from o in db.Orders where e.Region == o.ShipRegion select new { e.Region, o }).ToList(); var q6 = (from e in db.Employees from o in db.Orders where Equals(e.Region, o.ShipRegion) select new { e.Region, o }).ToList();

      CLR和SQL在數值精度上的差別,也常讓CLR拋OverFlow異常.這個很好判斷,如果Ado.Net拋這個異常了,那Linq To Sql肯定要拋,所以并不是Linq To Sql的問題。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    22/2<12

    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>