小分享:我有幾張阿裡雲優惠券,用券購買或者升級阿裡雲相應產品最多可以優惠五折!領券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03
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, 排序和分頁
在使用Skip和Take方法實現分頁時,必須先對數據進行排序,否則將會拋異常。
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, 聚合
可使用的聚合運算符有Average、Count、Max、Min 和 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異常,並顯示無法創建類型為“結束類型”的常量值。此上下文僅支持基元類型(“例如 Int32、String 和 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);
}
上面的代碼中,由於id是uint而不是Int32,String,Guid的標量類型,所以在執行到where p.UnitPrice ==id這個地方時,會報異常。
l 不支持引用非標量閉包
不支持在查詢中引用非標量閉包(如實體)。在執行這類查詢時,會引發 NotSupportedException 異常,並顯示消息“無法創建類型為“結束類型”的常量值。此上下文中僅支持基元類型(‘如 Int32、String 和 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是引用類型而不是Int32,String,Guid的標量類型,所以在執行到where c==customer這個地方時,會報異常。
好,本節介紹完畢。後面將繼續學習EF.
參考頁面:http://qingqingquege.cnblogs.com/p/5933752.html