查詢產生器方法 (Entity Framework)
ObjectQuery 類別支援對概念模型進行 LINQ to Entities 和 Entity SQL 查詢。 ObjectQuery 也會實作一組查詢產生器方法,這些方法可用來循序建構與 Entity SQL 相等的查詢命令。 下列是 ObjectQuery 的查詢產生器方法,連同相等的 Entity SQL 陳述式:
ObjectQuery 方法 | Entity SQL 陳述式 |
---|---|
每一個查詢產生器方法都會傳回新的 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 會實作 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) = 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");
注意: |
---|
使用 ToTraceString 方法可查看將會由 ObjectQuery 產生的資料來源命令。如需詳細資訊,請參閱物件查詢 (Entity Framework)。 |
別名
查詢產生器方法會循序套用,以建構累計查詢命令。 這表示目前的 ObjectQuery 命令會視為套用目前方法的子查詢。
注意: |
---|
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));
當您設定 ObjectQuery 的 Name 屬性時,該值會變成後續方法中的別名。 下列範例會擴充上一個範例,其方式是將 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 中必須是唯一的。 集合中不能有兩個參數同名。
當您使用構成方法 (如 Union、UnionAll、Intersect 和 Except) 時,將會合併參數集合。 當參數集合不相容、不完整或是兩個查詢的參數集合內有相同的名稱存在時,就會擲回例外狀況。