前面的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。