Share via


物件查詢 (Entity Framework)

ObjectQuery 泛型類別表示傳回零個或多個具型別實體物件之集合的查詢。物件查詢一定屬於某個現有的物件內容。此內容提供了撰寫及執行查詢所需的連接和中繼資料資訊。具型別 ObjectContext 所包含的屬性集,會傳回具型別 ObjectQuery 執行個體。模型中的每個實體類型都具有其中一個屬性。這些屬性可以讓具型別 ObjectQuery 執行個體的建立作業更為容易。以下情況下會執行物件查詢:

  • 當它有作用時,例如在 foreach (C#) 或 For Each (Visual Basic) 列舉型別期間。

  • 指派它來填滿 List 集合時。

  • 明確呼叫 Execute 方法時。

  • 當呼叫 LINQ 查詢執行運算子 (如 FirstAny) 時。如需詳細資訊,請參閱查詢產生器方法 (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 型別用於傳回非實體類型的投影,這可以是巢狀結果或匿名型別。簡單型別 (如 Int32String) 會搭配可傳回單一屬性值的投影一起使用。

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 上的 GetObjectByKeyTryGetObjectByKey 方法會將具有指定 EntityKey 的物件傳回到物件內容中。當您使用 GetObjectByKey 時,您必須在提供的 EntityKey 未對應到現有實體時處理 ObjectNotFoundException。如需詳細資訊,請參閱 HOW TO:使用特定物件的索引鍵傳回此物件 (Entity Framework)

另請參閱

概念

以物件形式查詢資料 (Entity Framework)