ADO.NET Entity Framework 对象查询(实体框架)

ObjectQuery <(Of <(<'T >)>)> 泛型类表示一个查询,该查询可以返回零个或零个以上类型化对象的集合。 ObjectQuery <(Of <(<'T >)>)> 属于包含编写和执行查询所必需的连接和元数据信息的 ObjectContext可以使用 new 运算符构造 ObjectQuery <(Of <(<'T >)>)>,并将查询字符串和对象上下文传递到该构造函数。 但是,更通用的方案是使用 ObjectContext 派生类的属性获取表示实体集的集合的 ObjectQuery <(Of <(<'T >)>)> 实例。 通常,通过由实体框架工具生成的类或通过 POCO 类创建 ObjectContext 的子类,且对象上下文中的属性返回作为 ObjectQuery <(Of <(<'T >)>)>(在 .NET Framework 版本 3.5 SP1 中)或作为 ObjectSet <(Of <(<'TEntity >)>)>(在 .NET Framework 版本 4)的实体集。 在类型化实体集的上下文中, ObjectSet <(Of <(<'TEntity >)>)> 类扩展 ObjectQuery <(Of <(<'T >)>)> 类以提供功能,例如,添加和删除对象。

默认的 ObjectQuery <(Of <(<'T >)>)> 提供返回指定类型的所有实体的起始查询。 通过将 LINQ to Entities 或查询生成器方法可以进一步优化此查询。

下面的示例对 Products 集合的对象上下文进行查询。

 

using (AdventureWorksEntities AWEntities =
                new AdventureWorksEntities())
{
    ObjectSet<Product> products = AWEntities.Products;
    IQueryable<Product> productsQuery =
                from product
                in products
                                       
                select product;

    Console.WriteLine(
                "Product Names:");
   
                foreach (
                var prod
                in productsQuery)
    {
        Console.WriteLine(prod.Name);
    }
}


查询执行

在以下情况下,将执行对象查询:

注意,如果作为查询执行的结果,数据源中没有返回任何结果,则结果将包含一个空白集合而不是 null

由实体框架执行的查询根据数据源中的数据进行计算,且结果将不反映对象上下文中的新对象。如果已将具有与所查询的实体相同的标识的实体附加到上下文,则将根据查询的 MergeOption 合并来自数据源的数据与上下文中已存在的数据。 若要获取缓存中的数据,请使用 ObjectStateManager 类的 GetObjectStateEntries 方法。 由于 ObjectStateManager 管理对象上下文内部的对象的状态,因此如果您需要获取已添加的、已修改的和未更改的所有对象,您可以将以下 EntityState 值的按位 OR 传递给 GetObjectStateEntries 方法: AddedModifiedUnchanged有关更多信息,请参见 联机  博客(可能为英文网页),它演示如何执行本地查询。

在下面的示例中,将调用 Execute 方法执行查询:

 

using (AdventureWorksEntities advWorksContext =
   
                new AdventureWorksEntities())
{
    ObjectSet<Product> query = advWorksContext.Products;

   
                // Execute the query and get the ObjectQueryResult.
    ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
   
                // Iterate through the collection of Product items.foreach (Product result
                in queryResult)
        Console.WriteLine(
                "{0}", result.Name);
}

查询投影

对象查询经常用于返回概念模型数据作为实体对象,但也可能返回嵌套结果和匿名投影的 DbDataRecord 对象,或可返回单个值集的基元 CLR 类型。

LINQ to Entities 和 Entity SQL 均支持查询投影。以下注意事项适用于查询投影:

  • 某些扩展方法要求使用包含多个结果的集合作为输入。如果 ObjectQuery <(Of <(<'T >)>)> 表示一个返回带单个标量结果的集合的查询,并且调用了这些扩展方法中的某个扩展方法,则将引发 ArgumentException 异常,如下面的示例中所示。

// Define a query projection that returns // a single scalar value rather than a collection.
ObjectQuery<Int32> scalarQuery =
   
                    new ObjectQuery<Int32>(
                    "100", advWorksContext);


                    // Calling an extension method that requires a collection// will result in an exception.bool hasValues = scalarQuery.Any();

 

   如果 ObjectQuery <(Of <(<'T >)>)> 可能在投影到某个基元类型时返回 null 值,则应使用该类型的可为 null 的版本。 下面的查询使用可为 null 的 DateTime,因为 SalesOrderHeader 对象的 ShipDate 属性可能返回 null 值。

 

  ObjectQuery<Nullable<DateTime>> shipDateQuery =
    advWorksContext.SalesOrderHeaders
    .Where(
                    "it.CustomerID = @contactId",
       
                    new ObjectParameter(
                    "contactId", contactId))
    .SelectValue<Nullable<DateTime>>(
                    "it.ShipDate");

有关更多信息,请参见 可以为 null 的类型(Visual Basic 编程指南)可以为 null 的类型(C# 编程指南)

查看存储命令

在查询概念模型时,实体框架将基于概念模型的 LINQ to Entities 和 Entity SQL 查询转换为针对数据源的等效查询。实体框架提供 ObjectQuery ..::..ToTraceString EntityCommand ..::..ToTraceString 方法,允许您在运行时查看这些存储命令而无需对数据源运行跟踪。 有关更多信息,请参见 如何:查看存储命令(实体框架)

通过对象的 EntityKey 检索对象

如果知道实体的键值,则可以从数据源中检索该实体,而无需显式创建并执行对象查询。ObjectContext 上的 GetObjectByKeyTryGetObjectByKey 方法将具有指定 EntityKey 的对象返回到对象上下文。 使用 GetObjectByKey 时,如果提供的 EntityKey 与现有实体不对应,则必须处理 ObjectNotFoundException有关更多信息,请参见 如何:使用特定对象的键返回特定对象(实体框架)

请参见

概念

 



 

posted @ 2010-12-29 18:48  子福当自强  阅读(466)  评论(0编辑  收藏  举报
悟道