查詢產生器方法 (Entity Framework)

ObjectQuery 類別支援對概念模型進行 LINQ to Entities 和 Entity SQL 查詢。 ObjectQuery 也會實作一組查詢產生器方法,這些方法可用來循序建構與 Entity SQL 相等的查詢命令。 下列是 ObjectQuery 的查詢產生器方法,連同相等的 Entity SQL 陳述式:

ObjectQuery 方法 Entity SQL 陳述式

Distinct

DISTINCT

Except

EXCEPT

GroupBy

GROUP BY

Intersect

INTERSECT

OfType

OFTYPE

OrderBy

ORDER BY

Select

SELECT

SelectValue

SELECT VALUE

Skip

SKIP

Top

TOPLIMIT

Union

UNION

UnionAll

UNION ALL

Where

WHERE

每一個查詢產生器方法都會傳回新的 ObjectQuery 執行個體。 如此可讓您建構一個查詢,而它的結果集是根據之前 ObjectQuery 執行個體序列的作業。 下列範例示範如何使用 Where 方法來依據 ProductID 篩選所傳回的 Product 物件。

' Return Product objects with the specified ID. 
Dim query As ObjectQuery(Of Product) = context.Products.Where("it.ProductID = @product", New ObjectParameter("product", productId))
// Return Product objects with the specified ID.
ObjectQuery<Product> query =
    context.Products
    .Where("it.ProductID = @product",
    new ObjectParameter("product", productId));

由於 ObjectQuery 會實作 IQueryableIEnumerable,所以將 ObjectQuery 所實作的查詢產生器方法結合 LINQ 特定的標準查詢運算子方法 (如 FirstCount) 是可行的。 LINQ 運算子並不會傳回 ObjectQuery,與查詢產生器方法不同。 如需詳細資訊,請參閱 Visual Studio 2008 文件中的標準查詢運算子概觀主題。

選取資料

根據預設,ObjectQuery 會傳回特定型別的零個或多個實體物件。 呼叫後續的查詢方法 (如 WhereOrderBy) 會影響原始 ObjectQuery 所傳回的物件集合。 某些方法 (如 SelectGroupBy) 會以 DbDataRecord 形式傳回資料的投影,而不是傳回實體類型。 如需詳細資訊,請參閱物件查詢 (Entity Framework)。 下列範例會傳回包含巢狀 SalesOrderHeader 實體類型的 DbDataRecord 物件集合。

' Define a query that returns a nested 
' DbDataRecord for the projection. 
Dim query As ObjectQuery(Of DbDataRecord) = context.Contacts.Select("it.FirstName, it.LastName, it.SalesOrderHeaders") _
                                            .Where("it.LastName = @ln", New ObjectParameter("ln", lastName))
// Define a query that returns a nested 
// DbDataRecord for the projection.
ObjectQuery<DbDataRecord> query =
    context.Contacts.Select("it.FirstName, "
        + "it.LastName, it.SalesOrderHeaders")
    .Where("it.LastName = @ln", new ObjectParameter("ln", lastName));

雖然會循序套用查詢產生器方法,但是建構 Entity SQL 所支援的相同巢狀子查詢類型是可行的。 若要這樣做,您必須在方法中以 Entity SQL 形式包含子查詢。 下列範例會在 Select 方法內使用 Entity SQL SELECT 子查詢來包含 LastName 記錄 (以巢狀方式置於結果集中,並依照姓氏的第一個字母順序排序):

' Define the query with a GROUP BY clause that returns 
' a set of nested LastName records grouped by first letter. 
Dim query As ObjectQuery(Of DbDataRecord) = _
    context.Contacts.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln") _
    .Select("it.ln AS ln, (SELECT c1.LastName FROM AdventureWorksEntities.Contacts AS c1 " & _
            "WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT").OrderBy("it.ln")
// Define the query with a GROUP BY clause that returns
// a set of nested LastName records grouped by first letter.
ObjectQuery<DbDataRecord> query =
    context.Contacts
    .GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln")
    .Select("it.ln AS ln, (SELECT c1.LastName " +
    "FROM AdventureWorksEntities.Contacts AS c1 " +
    "WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT")
    .OrderBy("it.ln");
Bb896238.note(zh-tw,VS.100).gif注意:
使用 ToTraceString 方法可查看將會由 ObjectQuery 產生的資料來源命令。如需詳細資訊,請參閱物件查詢 (Entity Framework)

別名

查詢產生器方法會循序套用,以建構累計查詢命令。 這表示目前的 ObjectQuery 命令會視為套用目前方法的子查詢。

Bb896238.note(zh-tw,VS.100).gif注意:
CommandText 屬性會針對 ObjectQuery 執行個體傳回命令。

在查詢產生器方法中,您會使用別名來參考目前的 ObjectQuery 命令。 根據預設,"it" 字串是代表目前命令的別名,如下列範例所示:

' Return Product objects with a standard cost 
' above 10 dollars. 
Dim cost = 10
Dim productQuery As ObjectQuery(Of Product) = context.Products.Where("it.StandardCost > @cost")
productQuery.Parameters.Add(New ObjectParameter("cost", cost))
int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
    context.Products
    .Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));

當您設定 ObjectQueryName 屬性時,該值會變成後續方法中的別名。 下列範例會擴充上一個範例,其方式是將 ObjectQuery 的名稱設定為 "product",然後在後續的 OrderBy 方法中使用這個別名:

' Return Product objects with a standard cost 
' above 10 dollars. 
Dim cost = 10
Dim productQuery As ObjectQuery(Of Product) = context.Products.Where("it.StandardCost > @cost")
productQuery.Parameters.Add(New ObjectParameter("cost", cost))

' Set the Name property for the query and then 
' use that name as the alias in the subsequent 
' OrderBy method. 
productQuery.Name = "product"
Dim filteredProduct As ObjectQuery(Of Product) = productQuery.OrderBy("product.ProductID")
int cost = 10;
// Return Product objects with a standard cost
// above 10 dollars.
ObjectQuery<Product> productQuery =
    context.Products
    .Where("it.StandardCost > @cost", new ObjectParameter("cost", cost));

// Set the Name property for the query and then 
// use that name as the alias in the subsequent 
// OrderBy method.
productQuery.Name = "product";
ObjectQuery<Product> filteredProduct = productQuery
    .OrderBy("product.ProductID");

參數

所有接受 Entity SQL 字串輸入的查詢產生器方法也支援參數化查詢。 Entity SQL 中的參數名稱會在查詢運算式內定義,使用 At (@) 符號當做前置詞。 如需詳細資訊,請參閱參數 (Entity SQL)。 參數會當做 ObjectParameter 執行個體的陣列傳遞給查詢產生器方法。 下列範例會將兩個參數傳遞給 Where 方法:

' Get the contacts with the specified name. 
Dim contactQuery As ObjectQuery(Of Contact) = context.Contacts.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.Contacts
    .Where("it.LastName = @ln AND it.FirstName = @fn",
    new ObjectParameter("ln", lastName),
    new ObjectParameter("fn", firstName));

使用參數的考量

當您搭配查詢產生器方法使用參數時,以下考量就會適用:

  • 傳遞給查詢產生器方法的參數是由序列中後續的 ObjectQuery 執行個體所彙總 (Aggregate)。 它們可以使用 Parameters 屬性來存取。 加入之後,就可以從集合中移除參數,而且只要尚未編譯或執行查詢,就可以清除此集合。 參數名稱無法變更,但是參數值則可以隨時變更。

  • 參數在 ObjectParameterCollection 中必須是唯一的。 集合中不能有兩個參數同名。

  • 當您使用構成方法 (如 UnionUnionAllIntersectExcept) 時,將會合併參數集合。 當參數集合不相容、不完整或是兩個查詢的參數集合內有相同的名稱存在時,就會擲回例外狀況。

另請參閱

概念

查詢概念模型 (Entity Framework)
載入相關的物件 (Entity Framework)