查询生成器方法(实体框架)
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 的数据的投影,而不是实体类型的投影。 有关更多信息,请参见对象查询(实体框架)。 下面的示例返回包含嵌套 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 生成的数据源命令。有关更多信息,请参见对象查询(实体框架)。 |
别名
查询生成器方法按顺序应用从而构造累计查询命令。 这意味着将像对待当前方法应用到的子查询一样来对待当前 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 中的参数名称在查询表达式中定义,并以 (@) 符号作为前缀。 有关更多信息,请参见参数 (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 的后续实例聚合。 可以使用 Parameters 属性访问这些参数。 添加参数后,只要还没有编译或执行查询,就可以从集合中移除参数,并且可以清除集合。 不能更改参数名称,但可以随时对值进行更改。
参数在 ObjectParameterCollection 中必须是唯一的。 集合中不能有两个具有相同名称的参数。
使用组合方法(例如 Union、UnionAll、Intersect 和 Except)时,将对参数集合进行合并。 当参数集合不兼容、不完整或者在两个查询的参数集合中存在相同的名称时,将引发异常。