在学习了EncityClient提供的实体数据后,就是学习ObjectContext类,用于操作对象形式的实体数据(EncityClient提供的实体数据)。可以这样来理解ObjectContext就是数据库的访问实体上下文。
1 ObjectContext类
1.1 构造函数
ObjectContext类重载了四个构造函数,但常用的是ObjectContext(EntityConnection connection),使用给定连接初始化 ObjectContext 类的新实例。 在构造过程中,从 EntityConnection 对象提取元数据工作区。
ObjectContext(EntityConnection, String),使用给定的连接和实体容器名称初始化 ObjectContext 类的新实例。实体容器的名称,就是定义的整个概念模型的名称,它相对于一个数据库的名称,例如:NorthwindEntities,往往会用“数据库名+Entities”来给实体容器命名。
1.2 常用属性
1.2.1 DefaultContainerName属性
获取或设置默认容器名称。如果通过受保护构造函数设置默认容器名称,则该属性为只读属性,即由ObjectContext(EntityConnection, String)构造的ObjectContext的DefaultContainerName 属性为只读。
1.3 常用方法
ObjectContext类提供了很多的方法用于操作实体对象。挑些常用的方法来学习。
1.3.1 CreateObjectSet<TEntity> 方法
创建实体集实例,用于创建一个ObjectSet<TEntity>实例,用于操作指定实体类型的对象,用ObjectSet类提供的方法对实体进行操作(包括创建、读取、删除、附加和更新)。
特定模型的 ObjectContext 类具有类型为 ObjectSet<(Of <(<'TEntity>)>)> 的属性,它们表示模型的实体集。CreateObjectSet 方法及其重载创建一个新的 ObjectSet<(Of <(<'TEntity>)>)> 实例。
例如:CustomersSet = CreateObjectSet< Customers>();创建数据库中Customers表所对应的概念模型中Customers模型的实例。
2 ObjectSet<TEntity>
实体集,表示用于执行创建、读取、更新和删除操作的实体集。它与ObjectContext同属于System.Data.Objects 命名空间。可以不完成正确的通俗的理解为一个表的记录集映射到概念模型中某模型实体的成员集。
ObjectSet<TEntity> 成员介绍请参见http://msdn.microsoft.com/zh-cn/library/dd412646.aspx。
2.1 AddObject 方法
往某一实体模型中添加一成员。
static void ObjectSet_AddObject(ObjectContext cont)
{
ObjectSet<Region> RegionSet = cont.CreateObjectSet<Region>();
var newRegion = new Region { RegionDescription ="广东"};
RegionSet.AddObject(newRegion);
cont.SaveChanges();
Console.WriteLine("添加“广东”成功!");
}
2.2 DeleteObject方法
往某一实体模型中删除一成员。
static void ObjectSet_DeleteObject(ObjectContext cont)
{
ObjectSet<Region> RegionSet = cont.CreateObjectSet<Region>();
Region _Region = RegionSet.Where("it.RegionID =@p",
new ObjectParameter("p", 0)).First();
RegionSet.DeleteObject(_Region);
cont.SaveChanges();
Console.WriteLine("将新添加的记录成功删除!");
}
2.3 CreateObject方法
创建一个新的实体类型对象。
static void ObjectSet_CreateObject(ObjectContext cont)
{
ObjectSet<Region> RegionSet = cont.CreateObjectSet<Region>();
var _Region = RegionSet.CreateObject();
_Region.RegionID = 0;
_Region.RegionDescription = "广东";
RegionSet.AddObject(_Region);
cont.SaveChanges();
Console.WriteLine("添加“广东”成功!");
}
2.4 Where方法
将查询限制为返回与指定筛选条件匹配的结果。
static void ObjectSet_ModifyObject(ObjectContext cont)
{
ObjectSet<Region> RegionSet = cont.CreateObjectSet<Region>();
Region _Region = RegionSet.Where("it.RegionDescription = @p",
new ObjectParameter ("p", "广东")).First();
_Region.RegionID = 0;
_Region.RegionDescription = "广西";
cont.SaveChanges();
Console.WriteLine("将id=" + _Region.RegionID.ToString() + " 广东改为广西");
}
3 ObjectQuery<T> 类
表示在给定的对象上下文中针对概念模型的类型化查询。该查询返回由零个或多个特定类型的对象组成的集合。 在执行对象查询之前,必须定义 ObjectContext。 此上下文提供编写和执行查询所必需的连接和元数据信息。
ObjectQuery<T> 成员介绍请参见http://msdn.microsoft.com/zh-cn/library/bb349034.aspx。
static void ObjectQuery_Sample(ObjectContext cont)
{
string queryString =
@"SELECT VALUE Region FROM NorthwindEntities.Region AS Region";
ObjectQuery<Region> RegionQuery1 =new ObjectQuery<Region>(queryString, cont);
foreach (Region result in RegionQuery1)
Console.WriteLine("RegionDescription: {0}", result.RegionDescription);
Console.WriteLine("带MergeOption.NoTracking参数查询出的记录:");
ObjectQuery<Region> RegionQuery2 = new ObjectQuery<Region>(queryString,
cont , MergeOption.NoTracking);
foreach (Region result in RegionQuery2)
Console.WriteLine("RegionDescription: {0}", result.RegionDescription);
}
3.1 构造函数
名称 |
说明 |
|
使用指定的 Entity SQL 命令作为初始查询来创建新的 ObjectQuery<T> 实例。 |
|
使用指定的 Entity SQL 命令(作为初始查询)和指定的合并选项来创建新的 ObjectQuery<T> 实例。 |
3.2 MergeOption 枚举
指定加载到对象上下文中的对象与对象上下文中的已有对象的合并方式。
成员名称 |
说明 |
AppendOnly |
对象上下文中不存在的对象将附加到该上下文。 如果该上下文中已存在对象,则该项中对象属性的当前值和原始值不会被数据源值覆盖。 该对象的项状态和项中对象的属性状态不会更改。 AppendOnly 是默认合并选项。 |
OverwriteChanges |
对象上下文中不存在的对象将附加到该上下文。 如果该上下文中已存在对象,则该项中对象属性的当前值和原始值将会被数据源值覆盖。 该对象的项状态将设置为 Unchanged,任何属性都不会标记为已修改。 |
PreserveChanges |
对象上下文中不存在的对象将附加到该上下文。 如果该实体的状态为 Unchanged,那么该输入中的当前值和原始值会被数据源值覆盖。 实体的状态仍保持 Unchanged,并且属性没有标记为已修改。 如果该实体的状态为 Modified,那么修改的属性的当前值不会被数据源值覆盖。 数据源中的值将覆盖原始的未修改属性的值。 在 .NET Framework 4 版中,Entity Framework 比较未修改的属性的当前值和从数据源返回的值。 如果这些值不相同,那么该属性将标记为已修改。 在 .NET Framework 3.5 SP1 版中,即使数据源中的值不同,Entity Framework 也不会将该属性标记为已修改。 当调用 SaveChanges 时,只有修改过的属性才会保留到数据源。 若要保留 3.5 SP1 行为,请将 UseLegacyPreserveChangesBehavior 设置为 true。 该 PreserveChanges 选项可用于在保留本地上下文中的更改的同时解决开放式并发异常。 有关更多信息,请参见Saving Changes and Managing Concurrency (Entity Framework)。 |
NoTracking |
对象保持为 Detached 状态,且未在 ObjectStateManager 中跟踪对象。 但是,Entity Framework 生成的实体和具有代理的 POCO 实体将维护对该对象上下文的引用以便于相关对象的加载。 |
3.3 Distinct 方法
将查询限制为仅返回唯一结果。
3.4 UnionAll 方法
将查询结果与另一个对象查询的结果进行组合(包括所有重复项)。
int productID = 100;
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
try
{
string queryString = @"SELECT VALUE product FROM AdventureWorksEntities.Products
AS product WHERE product.ProductID < @productID";
ObjectQuery<Product> productQuery = new ObjectQuery<Product>(queryString,
context, MergeOption.NoTracking);
ObjectQuery<Product> productQuery2 =new ObjectQuery<Product>(queryString,
context, MergeOption.NoTracking);
ObjectQuery<Product> productQuery3 = productQuery.UnionAll(productQuery2);
productQuery3.Parameters.Add(new ObjectParameter("productID", productID));
Console.WriteLine("Result of UnionAll");
Console.WriteLine("------------------");
foreach (Product result in productQuery3)
{
Console.WriteLine("Product Name: {0}", result.ProductID);
}
ObjectQuery<Product> productQuery4 = productQuery3.Distinct();
Console.WriteLine("\nResult of Distinct");
Console.WriteLine("------------------");
foreach (Product result in productQuery4)
Console.WriteLine("Product Name: {0}", result.ProductID);
}
catch (EntitySqlException ex)
{
Console.WriteLine(ex.ToString());
}
}
接下来转入LINQ To Entitys的学习。