定義 LINQ to SQL 查詢所用的語法與在 LINQ 中使用的語法相同。唯一的差異是您的查詢中引用的對象映射到數據庫中的元素。
查詢執行關系圖
下表顯示了 LINQ 與 LINQ to SQL 查詢項之間的相似和不同之處。
項 |
LINQ 查詢 |
LINQ to SQL 查詢 |
保存查詢的局部變量的返回類型(對於返回序列的查詢而言) |
泛型 IEnumerable |
泛型 IQueryable |
指定數據源 |
使用 From (Visual Basic) 或 from (C#) 子句 |
相同 |
篩選 |
使用 Where/ where 子句 |
相同 |
分組 |
使用 Group…By/ groupby 子句 |
相同 |
選擇(投影) |
使用 Select/ select 子句 |
相同 |
延遲執行與立即執行 |
請參見 LINQ 查詢簡介 (C#) |
相同 |
實現聯接 |
使用 Join/ join 子句 |
可以使用 Join/ join 子句,但使用 AssociationAttribute 屬性更有效。 有關更多信息,請參見 跨關系查詢 (LINQ to SQL)。 |
遠程執行與本地執行 |
|
有關更多信息,請參見 遠程查詢執行與本地查詢執行 (LINQ to SQL)。 |
流式查詢與緩存查詢 |
在本地內存情況中不適用 |
|
基本 LINQ 查詢操作 (C#)
獲取數據源
在 LINQ 查詢中,第一步是指定數據源。像在大多數編程語言中一樣,在 C# 中,必須先聲明變量,才能使用它。在 LINQ 查詢中,最先使用 from 子句的目的是引入數據源 ( customers) 和范圍變量 ( cust)。
var q = from c in customers
select c.OID,c.customername;
篩選
也許最常用的查詢操作是應用布爾表達式形式的篩選器。此篩選器使查詢只返回那些表達式結果為 true 的元素。使用 where 子句生成結果。 實際上,篩選器指定從源序列中排除哪些元素。
var q = from c in customers
where c.City == "London"
select c;
Where 操作中連接符號 && (與) || (或) ! (非)
排序 orderby c.Name ascending
. 返回集合中的第一個元素 相對於 Top 1
var q=db.GetTable<student>().First<student>();
. 查詢不重復的結果
var q=db.GetTable<student>().Distinct<student>();
分組 group by
在使用 group 子句結束查詢時,結果采用列表的列表形式。 列表中的每個元素是一個具有 Key 成員及根據該鍵分組的元素列表的對象。 在循環訪問生成組序列的查詢時,您必須使用嵌套的 foreach 循環。 外部循環用於循環訪問每個組,內部循環用於循環訪問每個組的成員。
var q = from c in customers
group c by c.City;
// customerGroup is an IGrouping<string, Customer>
foreach (var customerGroup in q)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
聯接
var q = from c in db.student
join o in db.@class on c.StudentName equals o.Student
select new { c.ID ,c.StudentName ,o.Class1 };
選擇(投影)
select 子句生成查詢結果並指定每個返回的元素的“形狀”或類型。 例如,您可以指定結果包含的是整個 Customer 對象、僅一個成員、成員的子集,還是某個基於計算或新對象創建的完全不同的結果類型。 當 select 子句生成除源元素副本以外的內容時,該操作稱為“投影”。 使用投影轉換數據是 LINQ 查詢表達式的一種強大功能。
2.重寫 Insert、Update 和 Delete 的默認行為。
LINQ to SQL 不強制滿足以下要求,但如果這些要求未得到滿足,就會導致行為不明確。
· 重寫方法不能調用 SubmitChanges 或 Attach。 如果在重寫方法中調用這些方法,LINQ to SQL 會引發異常。
· 重寫方法不能用來啟動、提交或停止事務。SubmitChanges 操作以事務的形式執行。 內嵌的事務可能會干擾外層事務。加載重寫方法只能在它們確定 Transaction 中未在執行相應操作后啟動事務。
· 重寫方法應遵循適用的開放式並發映射。發生開放式並發沖突時,重寫方法應引發 ChangeConflictException。 LINQ to SQL 會捕獲此異常,以便您可以正確處理 SubmitChanges 時提供的 SubmitChanges 選項。
· Create ( Insert) 和 Update 重寫方法在相應操作成功完成后應使數據庫生成的列的值流回對應的對象成員。
例如,如果 Order.OrderID 映射到標識列(autoincrement 主鍵),則 InsertOrder() 重寫方法必須檢索數據庫生成的 ID 並將 Order.OrderID 成員設置為該 ID。 同樣,時間戳成員必須更新為數據庫生成的時間戳值,以確保更新后的對象一致。如果未能傳播數據庫生成的值,則會造成數據庫與 DataContext 跟蹤的對象之間不一致。
· 調用正確的動態 API 是用戶的責任。例如,在更新重寫方法中,只能調用 ExecuteDynamicUpdate。 LINQ to SQL 不檢測或驗證調用的動態方法是否與適用的操作相匹配。如果調用了不適用的方法(例如,為要更新的對象調用了 ExecuteDynamicDelete),則結果是不明確的。
· 最后,重寫方法應執行明確的操作。LINQ to SQL 操作(如預先加載、延遲加載和 SubmitChanges))的語義要求重寫提供明確的服務。例如,只返回空集合而不檢查數據庫內容的加載重寫有可能會造成數據不一致。
3.設置適當的選項以檢測和報告並發沖突。
在 LINQ to SQL 對象模型中,當以下兩個條件都得到滿足時,就會發生“開放式並發沖突”:
· 客戶端嘗試向數據庫提交更改。
· 數據庫中的一個或多個更新檢查值自客戶端上次讀取它們以來已得到更新。
此沖突的解決過程包括查明對象的哪些成員發生沖突,然后決定您希望如何進行處理。
沖突檢測和解決檢查表
您可以檢測和解決任意詳細等級的沖突。一種極端情況是,您可以用三種方式之一(請參見 RefreshMode)來解決所有沖突,而不再作其他方面的考慮。 另一種極端情況是,您可以為發生沖突的每個成員上的每種沖突指定特定操作。
- 在您的對象模型中指定或修改 UpdateCheck 選項。
- 在對 SubmitChanges 的調用的 try/catch 塊中,指定您希望在哪個點引發異常。
- 決定您希望檢索的沖突詳細信息量,並在 try/catch 塊中包括相應的代碼。
- 在 try/ catch 代碼中包括您希望解決您發現的各種沖突的方式。
術語 |
說明 |
並發 |
兩個或更多用戶同時嘗試更新同一數據庫行的情形。 |
並發沖突 |
兩個或更多用戶同時嘗試向一行的一列或多列提交沖突值的情形。 |
並發控制 |
用於解決並發沖突的技術。 |
開放式並發控制 |
先調查其他事務是否已更改了行中的值,再允許提交更改的技術。 相比之下,保守式並發控制則是通過鎖定記錄來避免發生並發沖突。 之所以稱作開放式控制,是因為它將一個事務干擾另一事務視為不太可能發生。 |
沖突解決 |
通過重新查詢數據庫刷新出現沖突的項,然后協調差異的過程。 刷新對象時,LINQ to SQL 更改跟蹤器會保留以下數據:
LINQ to SQL 隨后會確定相應對象是否發生沖突(即它的一個或多個成員值是否已發生更改)。如果此對象發生沖突,LINQ to SQL 下一步會確定它的哪些成員發生沖突。 LINQ to SQL 發現的任何成員沖突都會添加到沖突列表中。 |