物件查詢 (Entity Framework)
ObjectQuery 泛型類別表示可以傳回零個或多個具型別物件之集合的查詢。 ObjectQuery 屬於 ObjectContext,其中包含撰寫及執行查詢所需的連接和中繼資料資訊。 您可以使用 new 運算子建構 ObjectQuery,並將查詢字串和物件內容傳遞給建構函式。 不過,更常見的情況是在 ObjectContext 衍生類別上使用屬性,以取得代表實體集之集合的 ObjectQuery 執行個體。 ObjectContext 通常會透過 Entity Framework 工具所產生之類別或您的 POCO 類別進行子類別化,而物件內容上的屬性會傳回實體集當做 ObjectQuery (在 .NET Framework 3.5 版 SP1 中) 或當做 ObjectSet (在 .NET Framework 4 版中)。 ObjectSet 類別會擴充 ObjectQuery 類別來提供功能,例如在具型別實體集的內容中加入及刪除物件。
預設的 ObjectQuery 會提供開始查詢,傳回指定之類型的所有實體。 此查詢可以使用 LINQ to Entities 或查詢產生器方法來進一步調整。
下列範例會查詢 Products
之集合的物件內容。
Using context As New AdventureWorksEntities
Dim products As ObjectSet(Of Product) = context.Products
Dim productsQuery = _
From product In products _
Select product
Console.WriteLine("Product Names:")
For Each product In productsQuery
Console.WriteLine(product.Name)
Next
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
IQueryable<Product> productsQuery = from product in context.Products
select product;
Console.WriteLine("Product Names:");
foreach (var prod in productsQuery)
{
Console.WriteLine(prod.Name);
}
}
查詢執行
發生於執行物件查詢時:
它是由 foreach (C#) 或 For Each (Visual Basic) 陳述式所列舉。
它是由集合作業 (例如 ToArray、ToDictionary 或 ToList) 所列舉。
已明確呼叫 Execute 方法。
LINQ 運算子 (例如 First 或 Any) 是在查詢的最外面部分中指定的。 如需詳細資訊,請參閱查詢產生器方法 (Entity Framework)。
請注意,如果查詢執行的結果,沒有從資料來源傳回任何結果,則結果將包含一個空集合而不是 null。
由 Entity Framework 所執行的查詢會針對資料來源中的資料進行評估,而且結果將不會反映物件內容中的新物件。 如果具有與正在查詢之實體相同識別的實體已經附加到內容中,則會根據查詢的 MergeOption 將資料來源中的資料與內容中已經存在的資料合併在一起。 若要取得快取中的資料,請在 ObjectStateManager 類別上使用 GetObjectStateEntries 方法。 ObjectStateManager 會管理物件內容中物件的狀態,所以如果您想要取得所有已經加入、修改及未變更的物件,您可以將下列 EntityState 值的位元 OR 傳遞給 GetObjectStateEntries 方法:Added、Modified、Unchanged。 如需詳細資訊,請參閱示範如何執行本機查詢的部落格 (英文)。
在下列範例中,會呼叫 Execute 方法來執行查詢:
Using context As New AdventureWorksEntities()
Dim query As ObjectSet(Of Product) = context.Products
' Execute the query and get the ObjectResult.
Dim queryResult As ObjectResult(Of Product) = query.Execute(MergeOption.AppendOnly)
' Iterate through the collection of Product items.
For Each result As Product In queryResult
Console.WriteLine("{0}", result.Name)
Next
End Using
using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
ObjectSet<Product> query = context.Products;
// Execute the query and get the ObjectResult.
ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
// Iterate through the collection of Product items.
foreach (Product result in queryResult)
Console.WriteLine("{0}", result.Name);
}
查詢投影
物件查詢通常用來傳回概念模型資料做為實體物件,但是它們可能也會針對巢狀結果和匿名投影傳回 DbDataRecord 物件,或者它們可以針對單一值組傳回基本 CLR 型別。
LINQ to Entities 和 Entity SQL 都支援查詢投影。 以下是適用於查詢投影的考量因素:
某些擴充方法必須將許多結果的集合當做輸入。 如果 ObjectQuery 代表的查詢會傳回具有單一純量結果的集合,而且呼叫了這些擴充方法的其中一個,則會擲回 ArgumentException,如下列範例所示。
' Define a query projection that returns ' a collection with a single scalar result. Dim scalarQuery As New ObjectQuery(Of Int32)("100", context) ' 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 collection with a single scalar result. ObjectQuery<Int32> scalarQuery = new ObjectQuery<Int32>("100", context); // 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 DateTime)) = _ context.SalesOrderHeaders.Where("it.CustomerID = @contactId", _ New ObjectParameter("contactId", contactId)).SelectValue(Of Nullable(Of DateTime))("it.ShipDate")
ObjectQuery<Nullable<DateTime>> shipDateQuery = context.SalesOrderHeaders .Where("it.CustomerID = @contactId", new ObjectParameter("contactId", contactId)) .SelectValue<Nullable<DateTime>>("it.ShipDate");
如需詳細資訊,請參閱可為 Null 的型別 (Visual Basic 程式設計指南) 或Nullable Types (C# Programming Guide)。
檢視儲存命令
當您查詢概念模型時,Entity Framework 會將根據概念模型的 LINQ to Entities 和 Entity SQL 查詢轉換成針對資料來源的同等查詢。 Entity Framework 會提供 System.Data.Objects.ObjectQuery.ToTraceString 和 System.Data.EntityClient.EntityCommand.ToTraceString 方法,它們可讓您在執行階段檢視這些儲存命令,而不必針對資料來源執行追蹤。 如需詳細資訊,請參閱 HOW TO:檢視存放區命令 (Entity Framework)。
根據物件的 EntityKey 來擷取物件
如果您知道某個實體的機碼值 (Key Value),您可以從資料來源擷取它,而不需要明確建立和執行物件查詢。 ObjectContext 上的 GetObjectByKey 和 TryGetObjectByKey 方法會將具有指定 EntityKey 的物件傳回到物件內容中。 當您使用 GetObjectByKey 時,您必須在提供的 EntityKey 未對應到現有實體時處理 ObjectNotFoundException。 如需詳細資訊,請參閱 HOW TO:使用特定物件的索引鍵傳回此物件 (Entity Framework)。
另請參閱
概念
查詢概念模型 (Entity Framework)
使用 ObjectSet (Entity Framework)
已編譯的查詢 (LINQ to Entities)