查詢產生器方法 (Entity Framework)
ObjectQuery 類別可支援針對 實體資料模型 (EDM) 的 LINQ 到實體 和 實體 SQL 查詢。ObjectQuery 也會實作一組查詢產生器方法,這些方法可用來循序建構與 實體 SQL 相等的查詢命令。下列是 ObjectQuery 的查詢產生器方法,連同相等的 實體 SQL 陳述式:
ObjectQuery 方法 | Entity SQL 陳述式 |
---|---|
每一個查詢產生器方法都會傳回新的 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 會實作 IQueryable 和 IEnumerable,所以將 ObjectQuery 所實作的查詢產生器方法結合 LINQ 特定的標準查詢運算子方法 (如 First 或 Count) 是可行的。LINQ 運算子並不會傳回 ObjectQuery,與查詢產生器方法不同。如需詳細資訊,請參閱 Visual Studio 2008 文件中的標準查詢運算子概觀主題。
選取資料
根據預設,ObjectQuery 會傳回特定型別的零個或多個實體物件。呼叫後續的查詢方法 (如 Where 和 OrderBy) 會影響原始 ObjectQuery 所傳回的物件集合。某些方法 (如 Select 和 GroupBy) 會以 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");
附註 |
---|
使用 ToTraceString 方法可查看將會由 ObjectQuery 產生的資料來源命令。如需詳細資訊,請參閱物件查詢 (Entity Framework)。 |
別名
查詢產生器方法會循序套用,以建構累計查詢命令。這表示目前的 ObjectQuery 命令會視為套用目前方法的子查詢。
附註 |
---|
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");
當您設定 ObjectQuery 的 Name 屬性時,該值會變成後續方法中的別名。下列範例會擴充上一個範例,其方式是將 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 中必須是唯一的。集合中不能有兩個參數同名。
當您使用構成方法 (如 Union、UnionAll、Intersect 和 Except) 時,將會合併參數集合。當參數集合不相容、不完整或是兩個查詢的參數集合內有相同的名稱存在時,就會擲回例外狀況。
另請參閱
概念
以物件形式查詢資料 (Entity Framework)
為查詢結果定形 (Entity Framework)