查询生成器方法(实体框架)

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 的数据的投影,而不是实体类型的投影。 有关更多信息,请参见对象查询(实体框架)。 下面的示例返回包含嵌套 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-cn,VS.100).gif注意:
使用 ToTraceString 方法可以查看将由 ObjectQuery 生成的数据源命令。有关更多信息,请参见对象查询(实体框架)

别名

查询生成器方法按顺序应用从而构造累计查询命令。 这意味着将像对待当前方法应用到的子查询一样来对待当前 ObjectQuery 命令。

Bb896238.note(zh-cn,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 中的参数名称在查询表达式中定义,并以 (@) 符号作为前缀。 有关更多信息,请参见参数 (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 中必须是唯一的。 集合中不能有两个具有相同名称的参数。

  • 使用组合方法(例如 UnionUnionAllIntersectExcept)时,将对参数集合进行合并。 当参数集合不兼容、不完整或者在两个查询的参数集合中存在相同的名称时,将引发异常。

另请参见

概念

查询概念模型(实体框架)
加载相关对象(实体框架)