Entity Framework 學習初級篇3-- LINQ TO Entities

iDotNetSpace發表於2009-05-13

LINQ 技術(即 LINQ to Entities)使開發人員能夠通過使用 LINQ 表示式和 LINQ 標準查詢運算子,直接從開發環境中針對 實體框架物件上下文建立靈活的強型別查詢。LINQ to Entities 查詢使用物件服務基礎結構。ObjectContext 類是作為 CLR 物件與 實體資料模型 進行互動的主要類。開發人員通過 ObjectContext 構造泛型 ObjectQuery 例項。ObjectQuery 泛型類表示一個查詢,此查詢返回一個由型別化實體組成的例項或集合。返回的實體物件可供更新並位於物件上下文中。以下是建立和執行 LINQ to Entities 查詢的過程:

1.     ObjectContext 構造 ObjectQuery 例項。

2.     通過使用 ObjectQuery 例項在 C# Visual Basic 中編寫 LINQ to Entities 查詢。

3.     LINQ 標準查詢運算子和表示式將轉換為命令目錄樹。

4.     對資料來源執行命令目錄樹表示形式的查詢。執行過程中在資料來源上引發的任何異常都將直接向上傳遞到客戶端。

5.     將查詢結果返回到客戶端。

一、Linq To Entities簡單查詢

下面將介紹簡單的Linq To Entities查詢,相關的查詢語法可以使用基於表示式或基於方法的語法。本節使用的TestDriver.Net配合Nunit2.4進行測試。

1,  投影

程式碼如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Data.Objects;

using NUnit.Framework;

namespace NorthWindModel

{

    [TestFixture]

    public class TestEFModel

    {

        [Test]

        public void Select()

        {

            using (var edm = new NorthwindEntities())

            {

                //基於表示式的查詢語法

                ObjectQuery<Customers> customers = edm.Customers;

                IQueryable<Customers> cust1 = from c in customers

                                              select c;

                Assert.Greater(cust1.Count(), 0);

                //使用ObjectQuery類的ToTraceString()方法顯示查詢SQL語句

                Console.WriteLine(customers.ToTraceString());

 

 

            }

        }

    }

}

輸出:

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]

 

1 passed, 0 failed, 0 skipped, took 11.00 seconds (NUnit 2.4).

在上面的輸出內容中,可以看到使用了ToTraceString()方法來輸出具體的SQL語句。同時Nunit也輸出相關的測試情況,請注意查詢所花費的時間,以便我們進行查詢速度的分析比較。

2,  條件限制

using (var edm = new NorthwindEntities())

{

    //基於表示式的查詢語法

    ObjectQuery<Customers> customers = edm.Customers;

    IQueryable<Customers> cust1 = from c in customers

                                  where c.CustomerID == "ALFKI"

                                  select c;

  

    Assert.AreEqual(cust1.Count(), 1);

    foreach (var c in cust1)

        Console.WriteLine("CustomerID={0}", c.CustomerID);

               

    //基於方法的查詢語法

    var cust2 = edm.Customers.Where(c => c.CustomerID == "ALFKI");

    Assert.AreEqual(cust2.Count(), 1);

    foreach (var c in cust2)

          Console.WriteLine("CustomerID={0}", c.CustomerID);

 

}

3,  排序和分頁

在使用SkipTake方法實現分頁時,必須先對資料進行排序,否則將會拋異常。

using (var edm = new NorthwindEntities())

 {

//基於表示式的查詢語法

         ObjectQuery<Customers> customers = edm.Customers;

         IQueryable<Customers> cust10 = (from c in customers

                                         orderby c.CustomerID

                                         select c).Skip(0).Take(10);

 

          Assert.AreEqual(cust10.Count(), 10);

          foreach (var c in cust10)

              Console.WriteLine("CustomerID={0}", c.CustomerID);

   

//基於方法的查詢語法

    var cust = edm.Customers.OrderBy(c => c.CustomerID).Skip(0).Take(10);

    Assert.AreEqual(cust.Count(), 10);

    foreach (var c in cust)

        Console.WriteLine("CustomerID={0}", c.CustomerID);

  }

4,  聚合

可使用的聚合運算子有AverageCountMaxMin Sum

using (var edm = new NorthwindEntities())

   {

       var maxuprice = edm.Products.Max(p => p.UnitPrice);

       Console.WriteLine(maxuprice.Value);

 }

5,  連線

可以的連線有Join GroupJoin 方法。GroupJoin組聯接等效於左外部聯接,它返回第一個(左側)資料來源的每個元素(即使其他資料來源中沒有關聯元素)。

using (var edm = new NorthwindEntities())

    {

       var query = from d in edm.Order_Details

                   join order in edm.Orders

                   on d.OrderID equals order.OrderID

                   select new

                    {

                        OrderId = order.OrderID,

                        ProductId = d.ProductID,

                        UnitPrice = d.UnitPrice

                     };

        foreach (var q in query)

         Console.WriteLine("{0},{1},{2}",q.OrderId,q.ProductId,q.UnitPrice);

}

其他一些方法等就不多說了,和Linq to SQL 基本上是一樣的。

二、LINQ to Entities 查詢注意事項

l           排序資訊丟失

如果在排序操作之後執行了任何其他操作,則不能保證這些附加操作中會保留排序結果。這些操作包括 Select Where 等。另外,採用表示式作為輸入引數的 First FirstOrDefault 方法不保留順序。

如下程式碼:並不能達到反序排序的效果

using (var edm = new NorthwindEntities())

{

     IQueryable<Customers> cc = edm.Customers.OrderByDescending(c => c.CustomerID).Where(c => c.Region != null).Select(c => c);

     foreach (var c in cc)

          Console.WriteLine(c.CustomerID);

}

l           不支援無符號整數

由於 實體框架不支援無符號整數,因此不支援在 LINQ to Entities 查詢中指定無符號整數型別。如果指定無符號整數,則在查詢表示式轉換過程中會引發 NotSupportedException異常,並顯示無法建立型別為“結束型別”的常量值。此上下文僅支援基元型別(“例如 Int32String Guid)

如下將會報異常的程式碼:

using (var edm = new NorthwindEntities())

 {

      uint id = UInt32.Parse("123");

      IQueryable<string> produt = from p in edm.Products

                                  where p.UnitPrice == id

                                  select p.ProductName;

      foreach (string name in produt)

            Console.WriteLine(name);

}

上面的程式碼中,由於iduint而不是Int32StringGuid的標量型別,所以在執行到where p.UnitPrice ==id這個地方時,會報異常。

l           不支援引用非標量閉包

不支援在查詢中引用非標量閉包(如實體)。在執行這類查詢時,會引發 NotSupportedException 異常,並顯示訊息無法建立型別為“結束型別”的常量值。此上下文中僅支援基元型別(‘ Int32String Guid’)

如下將會報異常的程式碼:

using (var edm = new NorthwindEntities())

 {

        Customers customer = edm.Customers.FirstOrDefault();

        IQueryable<string> cc = from c in edm.Customers

                                where c == customer

                                select c.ContactName;

         foreach (string name in cc)

               Console.WriteLine(name);

}

上面的程式碼中,由於customer是引用型別而不是Int32StringGuid的標量型別,所以在執行到where c==customer這個地方時,會報異常。

原文地址:http://www.cnblogs.com/xray2005/archive/2009/05/09/1453036.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-594965/,如需轉載,請註明出處,否則將追究法律責任。

相關文章