物件查詢 (Entity Framework)
ObjectQuery 泛型類別表示傳回零個或多個具型別實體物件之集合的查詢。物件查詢一定屬於某個現有的物件內容。此內容提供了撰寫及執行查詢所需的連接和中繼資料資訊。具型別 ObjectContext 所包含的屬性集,會傳回具型別 ObjectQuery 執行個體。模型中的每個實體類型都具有其中一個屬性。這些屬性可以讓具型別 ObjectQuery 執行個體的建立作業更為容易。以下情況下會執行物件查詢:
當它有作用時,例如在 foreach (C#) 或 For Each (Visual Basic) 列舉型別期間。
指派它來填滿 List 集合時。
明確呼叫 Execute 方法時。
當呼叫 LINQ 查詢執行運算子 (如 First 或 Any) 時。如需詳細資訊,請參閱查詢產生器方法 (Entity Framework)。
下列查詢會傳回由傳遞之參數指定姓名的 Contact 物件:
' Get the contacts with the specified name.
Dim contactQuery As ObjectQuery(Of Contact) = _
context.Contact _
.Where("it.LastName = @ln AND it.FirstName = @fn", _
New ObjectParameter("ln", lastName), _
New ObjectParameter("fn", firstName))
// Get the contacts with the specified name.
ObjectQuery<Contact> contactQuery = context.Contact
.Where("it.LastName = @ln AND it.FirstName = @fn",
new ObjectParameter("ln", lastName),
new ObjectParameter("fn", firstName));
如需如何使用物件內容來撰寫及執行查詢的完整範例,請參閱 HOW TO:執行傳回實體類型的查詢 (Entity Framework)。如需有關 實體 SQL 查詢的詳細資訊,請參閱 Entity SQL 語言。
查詢投影
雖然物件查詢是用來傳回 實體資料模型 (EDM) 資料當做實體物件,但是物件查詢也可支援傳回資料的投影,而這些資料將無法輕鬆地具體化成實體類型。ObjectQuery 會將 DbDataRecord 型別用於傳回非實體類型的投影,這可以是巢狀結果或匿名型別。簡單型別 (如 Int32 或 String) 會搭配可傳回單一屬性值的投影一起使用。
Select 查詢產生器方法會傳回 ObjectQuery,而當執行後者時,會傳回 DbDataRecord 物件的集合。LINQ 到實體 和 實體 SQL 都支援查詢投影。如需查詢投影的範例,請參閱下列主題:
以下是適用於查詢投影的考量:
ObjectQuery 可初始化,好讓它代表單一純量結果,而不是純量結果的集合。某些擴充方法必須將集合結果當做輸入。在此情況下,當呼叫其中一個方法時會擲回 ArgumentException,如下列範例所示。
' Define a query projection that returns ' a single scalar value rather than a collection. Dim scalarQuery As ObjectQuery(Of Int32) = _ New ObjectQuery(Of Int32)("100", advWorksContext) ' Calling an extension method that requires a collection ' will result in an exception. Dim hasValues As Boolean = scalarQuery.Any()
// Define a query projection that returns // a single scalar value rather than a collection. ObjectQuery<Int32> scalarQuery = new ObjectQuery<Int32>("100", advWorksContext); // Calling an extension method that requires a collection // will result in an exception. bool hasValues = scalarQuery.Any();
如果 ObjectQuery 在投影為基本型別時可能會傳回 null 值,您應該使用此型別可為 Null 的版本。下列查詢使用可為 Null 的 DateTime,因為 SalesOrderHeader 物件的 ShipDate 屬性可能會傳回 null 值。
Dim shipDateQuery As ObjectQuery(Of Nullable(Of Date)) = _ advWorksContext.SalesOrderHeader _ .Where("it.CustomerID = @contactId", _ New ObjectParameter("contactId", contactId)) _ .SelectValue(Of Nullable(Of Date))("it.ShipDate")
ObjectQuery<Nullable<DateTime>> shipDateQuery = advWorksContext.SalesOrderHeader .Where("it.CustomerID = @contactId", new ObjectParameter("contactId", contactId)) .SelectValue<Nullable<DateTime>>("it.ShipDate");
如需詳細資訊,請參閱可為 Null 的型別 (Visual Basic 程式設計指南) 或可為 Null 的型別 (C# 程式設計手冊)。
設定命令逾時
物件查詢和 SaveChanges 作業的預設逾時是由基礎連接提供者所定義。但是,您可以在 ObjectContext 上使用 CommandTimeout 屬性來覆寫這個預設逾時值,如下列範例所示。
' Specify a timeout for queries in this context, in seconds.
context.CommandTimeout = 120
// Specify a timeout for queries in this context, in seconds.
context.CommandTimeout = 120;
當您具有複雜的查詢,或是當其他效能問題造成查詢或 SaveChanges 的呼叫經常逾時的時候,請進行這項處理。
檢視儲存命令
當您查詢 EDM 時,實體架構 會將根據 EDM 的 LINQ to Entities 和 實體 SQL 查詢轉換成針對資料來源的同等查詢。物件服務會提供 ToTraceString 方法,此方法可讓您在執行階段針對 ObjectQuery 檢視這些儲存命令,而不必針對資料來源執行追蹤。EntityClient 提供者也在 EntityCommand 上提供了 ToTraceString 方法。如需詳細資訊,請參閱 HOW TO:檢視存放區命令 (Entity Framework)。
根據物件的 EntityKey 來擷取物件
如果您知道某個實體的關鍵值 (Key Value),您可以從資料來源擷取它,而不需要明確建立和執行物件查詢。ObjectContext 上的 GetObjectByKey 和 TryGetObjectByKey 方法會將具有指定 EntityKey 的物件傳回到物件內容中。當您使用 GetObjectByKey 時,您必須在提供的 EntityKey 未對應到現有實體時處理 ObjectNotFoundException。如需詳細資訊,請參閱 HOW TO:使用特定物件的索引鍵傳回此物件 (Entity Framework)。