共用方式為


查詢產生器方法 (Entity Framework)

ObjectQuery 類別可支援針對 實體資料模型 (EDM) 的 LINQ 到實體 和 實體 SQL 查詢。ObjectQuery 也會實作一組查詢產生器方法,這些方法可用來循序建構與 實體 SQL 相等的查詢命令。下列是 ObjectQuery 的查詢產生器方法,連同相等的 實體 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) = _
advWorksContext.Product _
.Where("it.ProductID = @product", _
New ObjectParameter("product", productId))
// Return Product objects with the specified ID.
ObjectQuery<Product> query =
    advWorksContext.Product
    .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) = _
    advWorksContext.Contact.Select("it.FirstName, " _
        + "it.LastName, it.SalesOrderHeader") _
    .Where("it.LastName = 'Zhou'")
// Define a query that returns a nested 
// DbDataRecord for the projection.
ObjectQuery<DbDataRecord> query =
    advWorksContext.Contact.Select("it.FirstName, "
        + "it.LastName, it.SalesOrderHeader")
    .Where("it.LastName = 'Zhou'");

雖然會循序套用查詢產生器方法,但是建構 實體 SQL 所支援的相同巢狀子查詢類型是可行的。若要這樣做,您必須在方法中以 實體 SQL 形式包含子查詢。下列範例會在 Select 方法內使用 實體 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) = _
advWorksContext.Contact _
.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln") _
.Select("it.ln AS ln, (SELECT c1.LastName " + _
"FROM AdventureWorksEntities.Contact 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 =
    advWorksContext.Contact
    .GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln")    
    .Select("it.ln AS ln, (SELECT c1.LastName " +
    "FROM AdventureWorksEntities.Contact AS c1 " +
    "WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT")
    .OrderBy("it.ln");
Note附註

使用 ToTraceString 方法可查看將會由 ObjectQuery 產生的資料來源命令。如需詳細資訊,請參閱物件查詢 (Entity Framework)

別名

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

Note附註

CommandText 屬性會針對 ObjectQuery 執行個體傳回命令。

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

' Return Product objects with a standard cost
' above $10.
Dim productQuery As ObjectQuery(Of Product) = _
advWorksContext.Product _
    .Where("it.StandardCost > 10")
// Return Product objects with a standard cost
// above $10.
ObjectQuery<Product> productQuery =
    advWorksContext.Product
    .Where("it.StandardCost > 10");

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

' Return Product objects with a standard cost
' above $10.
Dim productQuery As ObjectQuery(Of Product) = _
advWorksContext.Product _
    .Where("it.StandardCost > 10")

'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")
// Return Product objects with a standard cost
// above $10.
ObjectQuery<Product> productQuery =
    advWorksContext.Product
    .Where("it.StandardCost > 10");

// 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");

參數

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

' 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));

使用參數的考量

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

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

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

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

另請參閱

概念

以物件形式查詢資料 (Entity Framework)
為查詢結果定形 (Entity Framework)

其他資源

查詢 Entity Data Model (Entity Framework 工作)