关于EF4里的 “关系”删除行为的解释
来源:互联网 发布:域名投资app 编辑:程序博客网 时间:2024/06/11 08:11
关于EF4里,对于拥有外键约束的实体,删除操作的行为及解释!(因为是翻墙找到的文章,所以复制过来方便大家查阅。)
[ 自己的总结:在master-detail结构的表处理时,例如下面例3的Order-OrderDetail,如果从某一个Order实体的OrderDetail集合中删除某个子对象,EF仅仅是删除关系而不是删除实体(此时该实体状态反而是Added,原因见下文),正确做法是从Context的OrderDetail实体集调用DeleteObject(或Context . DeleteObject)进行删除。 ]
-------------------
那么,当使用主从DataGridView通过2个BindingSource进行界面操作时,仅通过指定"子BindingSource”的DataSource和DataMember是不行的,只能将子BindingSource的DataSource也指定到Context下的从表集合进行过滤后绑定。当然,也可以用前一种方法绑定,保存时判断“孤”子对象从而进行Detach,个人认为麻烦些。
=====首先是问题场景的提出,接着是Daniel Simmons - MSFT 给出的解释=====
Saturday, January 30, 2010
Entity Framework v4 Object-Graph Deleting Quirks
I’ve been getting up to speed on Entity Framework V4 (EF4) lately, for use in a WPF application that I’m working on. One of the issues I’m coming up against is removal of objects in one-to-many and many-to-many relationships. It’s still not clear to me why things work the way they do in EF4, but I’ll lay out a few scenarios and talk about what works and what doesn’t work and hope that someone can later comment as to why things may not be working as I would expect.
Scenario 1: A many-to-many relationship where the join table has its own primary key (an identity column in this case):
Given the following code, I’d expect to be able to remove an object from the Employee.ProjectAssignments collection and see that object removed from the database when I call SaveChanges on my ObjectContext:
using (var context = new EFTestDBEntities()){
var employeeGraph = (from e in context.Employees.Include("ProjectAssignments").Include("ProjectAssignments.Project") where e.ID == employeeID select e).FirstOrDefault();
if (employeeGraph != null){
var assignment = employeeGraph.ProjectAssignments.First();
employeeGraph.ProjectAssignments.Remove(assignment);
context.SaveChanges();
}
}
When I hit the “SaveChanges()” call, I get the following exception:
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
This strikes me as strange – I assume that I’ve indicated that the employee is no longer related to this project-assignment, so the object is essentially “worthless” and I’d expect it to be removed.
In order to successfully remove this project-assignment, I had to do the following:
using (var context = new EFTestDBEntities()){
var employeeGraph = (from e in context.Employees.Include("ProjectAssignments").Include("ProjectAssignments.Project") where e.ID == employeeID select e).FirstOrDefault();
if (employeeGraph != null){
ProjectAssignment assignment = employeeGraph.ProjectAssignments.First();
context.ProjectAssignments.DeleteObject(assignment);
context.SaveChanges();
Assert.AreEqual(0, employeeGraph.ProjectAssignments.Count);
}
}
Okay, so if I “manually” delete the object by the explicit call to DeleteObject, things work. So far so good, I can work with this.
Scenario 2: A many-to-many relationship where the join table has a primary key that is composed by foreign-keys to the tables on either side of the relationship:
In this case, the code I’d expect to work, actually worked and allowed me to delete a class-schedule from a teacher:
using (var context = new EFTestDBEntities()){
var teacherGraph = (from t in context.Teachers.Include("ClassSchedules").Include("ClassSchedules.Class") where t.ID == teacherID select t).FirstOrDefault();
if(teacherGraph != null){
var classSchedule = teacherGraph.ClassSchedules.First();
teacherGraph.ClassSchedules.Remove(classSchedule);
context.SaveChanges();
}
}
Why does EF4 make a distinction in behavior between these two scenarios that are essentially the same operation yet one object-graph allows me to write what I naturally want to write (scenario 2), but not the other?
Scenario 3: A one-to-many relationship:
Once again, I tried to write the code in a way I’d expect to naturally work:
using (var context = new EFTestDBEntities()){
var orderGraph = (from o in context.Orders.Include("OrderDetails") where o.ID == orderID select o).FirstOrDefault();
if(orderGraph != null){
var detail = orderGraph.OrderDetails.First();
orderGraph.OrderDetails.Remove(detail);
context.SaveChanges();
}
}
And once again, I got the following exception:
System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
As with scenario 1, I had to write the following code to successfully remove the OrderDetail record:
using (var context = new EFTestDBEntities()){
var orderGraph = (from o in context.Orders.Include("OrderDetails") where o.ID == orderID select o).FirstOrDefault();
if (orderGraph != null){
var detail = orderGraph.OrderDetails.First();
context.OrderDetails.DeleteObject(detail);
context.SaveChanges();
}
}
Alright, so I have managed to work around some of the quirks with EF4, but I really don’t understand why removal of objects in the object-graph don’t cause a proper remove/delete in some cases, yet work just as I expect in others.
Deleting Foreign-Key Relationships in EF4
- 关于EF4里的 “关系”删除行为的解释
- MVC3+EF4.1----- ORM关系的处理
- 关于EF4.0中多对多关系的添加与修改的解决方案(MVC)
- 关于EF4.1更新数据后的显示问题-----PagedList
- 关于JFrame里setbackground()失效的解释
- 关于PHP与Apache关系的解释
- Dota里的行为经济学
- EF4 POCO 树形结构实体的创建
- 关于域名到期删除规则实施的解释
- vc里的数据类型解释
- 关于删除Xcode里多余的证书授权文件
- MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决
- MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决
- MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决
- MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决
- 依赖关系注入之后的行为
- 关于C的未定义行为
- 关于serialVersionUID的解释
- Red hat 关闭 SELINUX
- 带外数据OOB与紧急模式URG
- Message,MessageQueue,Looper,Handler详解+实例
- 媒体播放器三大底层架构
- geoserver 绘制地图 "rendering process failed / by zero"
- 关于EF4里的 “关系”删除行为的解释
- VBScript类型转换函数
- httpclient添加代理
- extjs 之 list checkbox
- 看来我要好好学习一下,我的专业外语了
- Linux内核引导参数简介
- 根据UILabel内容调节UILabel的大小
- 我是不是得工作恐惧症了
- Windows上cwRsync备份服务器数据