ADO.NET Entity Framework 深入分析, Part 5
 
2008-12-10 来源:EntLib.com
 

前面的Part 1-4的文章,介绍了Entity Data Model、Entity SQL、ObjectQuery、EntityCommand、LINQ to Entities等等及其代码演示。Part 4主要演示如何通过相关技术或Debug工具,如SQL Server Profiler、ToTraceString 方法、eSqlBlast 工具、LINQPad工具等等,来查看生成的T-SQL脚本。本篇文章Part 5 演示如何新增、更新和删除数据实体,并相应更新数据库。

ADO.NET Entity Framework 系列文章由EntLib.com 开源论坛、小组翻译、编写。欢迎交流、分享。

本系列文章前面部分链接:

增加、更新和删除实体

将实体的更新操作应用到数据库很方便。对象服务(Object Services)将记录所有对实体对象的改变,并产生和执行相应的T-SQL语句,对数据库实施插入、更新和删除操作。

通过调用ObjectContext的SaveChanges() 方法,来实现对数据库的更新,这与LINQ to SQL 的DataContext的SubmitChanges() 方法比较相似。

更新或修改实体

NorthwindEntities context = new NorthwindEntities();
 
Employee firstEmployee = context.Employees.First(e => e.EmployeeID == 1);
 
if (firstEmployee != null)
{
 firstEmployee.City = "San Francisco";
 firstEmployee.Notes = "New notes for employee 1";
 int affected = context.SaveChanges();
}

1) 检索一个Employee

LINQ to Entities 中,你可以使用扩展方法First(),因为SingleOrDefault() 方法将抛出NotSupportedException 异常(The 'Single' operator is not supported by LINQ to Entities. Consider using 'First' instead)。

2) 改变实体的一些属性

3) 调用ObjectContext 的SaveChanges() 方法,该方法将返回增加、修改或删除的实体对象的数量。

增加一个实体对象

Employee newEmployee = new Employee();
newEmployee.FirstName = "Jan";
newEmployee.LastName = "Jansen";
 
context.AddToEmployees(newEmployee);
 
context.SaveChanges();

1) 创建一个新的Employee 对象,并设置属性。

创建实体类之后,每一个生成的类都有一个静态的创建工厂方法。因此,你也可以使用CreateEmployee() 方法实例化一个Employee 对象和非空的属性。

如果细心一点,你将注意到EmployeeID 也是一个必须的字段。当然,这不是完全真实的,因为这是一个自增长的字段,由SQL Server 数据库来填充。在LINQ to SQL中,每一个属性成员有Auto Generated选项。Entity Framework 则没有这些,可能是因为它设计用来支持所有的数据库,可能一些数据库不支持AutoIncrement 数据类型,因此仅仅传递一个虚值。

Employee newEmployee = Employee.CreateEmployee(0, "Jansen", "Jan");

2) 调用ObjectContext对象的AddToEmployees() 方法。这与LINQ to SQL不一样,LINQ to SQL使用 Employees集合的InsertOnSubmit() 方法。在Entity Framework中,每一个EntityType自动生成指定的AddTo 方法。

你也可以使用对象上下文(Object Context) 的AddObject() 方法,第一个参数是Entity Set的名称,我个人喜好使用AddTo 方法。

context.AddObject("Employees", newEmployee);

3) 调用Object Context 的SaveChanges() 方法。

增加实体及其关联实体

Category newCategory = new Category();
newCategory.CategoryName = "Software";
newCategory.Description = "Software products";
 
newCategory.Products.Add(new Product() { ProductName = "Microsoft Visual Studio 2008" });
newCategory.Products.Add(new Product() { ProductName = "Microsoft Office 2007" });
 
context.AddToCategories(newCategory);
 
context.SaveChanges();
 
1) 创建一个新的Category 对象并设置属性。
2) 当你创建的实体通过Navigation 属性关联到另一个实体时,你可以调用集合Add() 方法。创建2个新的Product对象,并添加这2个对象到Category的Products集合。
3) 调用Object Context的AddToCategories() 方法。
4) 调用Object Context 的SaveChanges() 方法。
将执行如下3条T-SQL脚本:
exec sp_executesql N'insert [dbo].[Categories]([CategoryName], [Description], [Picture])
values (@0, @1, null)
select [CategoryID]
from [dbo].[Categories]
where @@ROWCOUNT > 0 and [CategoryID] = scope_identity()',N'@0 nvarchar(8),@1 nvarchar(17)',@0=N'Software',@1=N'Software products'
 
exec sp_executesql N'insert [dbo].[Products]([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice],
 [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued])
values (@0, null, @1, null, null, null, null, null, @2)
select [ProductID]
from [dbo].[Products]
where @@ROWCOUNT > 0 and [ProductID] = scope_identity()',N'@0 nvarchar(28),@1 int,@2 bit',@0=N'Microsoft Visual Studio 2008',@1=12,@2=0
 
exec sp_executesql N'insert [dbo].[Products]([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice],
 [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued])
values (@0, null, @1, null, null, null, null, null, @2)
select [ProductID]
from [dbo].[Products]
where @@ROWCOUNT > 0 and [ProductID] = scope_identity()',N'@0 nvarchar(21),@1 int,@2 bit',@0=N'Microsoft Office 2007',@1=12,@2=0

删除一个实体对象

Category cat = context.Categories.First(c => c.CategoryName == "Software");
context.DeleteObject(cat);
context.SaveChanges();
 
1) 检索一个Category 对象。
2) 调用Object Context 的DeleteObject() 的方法,并传入Category 对象。编写一个重载的方法,仅需要一个EntityKey,这也是可行的。
3) 调用Object Context 的SaveChanges() 方法。

在默认的Northwind 数据库,上述示例将抛出一个异常:"The DELETE statement conflicted with the REFERENCE constraint "FK_Products_Categories". The conflict occurred in database "Northwind", table "dbo.Products", column "CategoryID". The statement has been terminated."

如果你想删除Software目录和它的产品,你需要修改SQL Server数据库中FK_Products_Categories 外键的Delete Rule,并设置为Cascade。


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织