EF一对多关系删除问题
在使用EF删除一对多关系的实体时,碰到如下提示:
“其他信息: 操作失败: 无法更改关系,因为一个或多个外键属性不可以为 null。对关系作出更改后,会将相关的外键属性设置为 null 值。如果外键不支持 null 值,则必须定义新的关系,必须向外键属性分配另一个非 null 值,或必须删除无关的对象。”
原因很简单,假设一个A对应多个B,那么B中的外键就是A的主键,如果先删除A,接着又把B读取到datacontext中
var lstB = a.B.ToList();
container.A.DeleteObject(a);
就会导致B中的外键失去关联,所以便产生了错误,解决的办法有下面几种:
1.将子表外键解除与主表的关联
如果仅仅是需要删除A,而不删除B,那么需要解除B与A的关联(一般情况下不这样做,都是删除A并且删除B)。代码如下:
1 | var lstB = a.B.ToList(); |
如果B的外键可以为null,那么可以改成
b.Aid = null;
2.先删除子表再删除主表
这是正常的操作方式,首先删除与A对应的所有的B,再删除A即可。不过在操作中却遇到了另外一个问题。
1 | foreach (B b in a.B) |
foreach操作看似简单方便,但却忽略了一点:这是一个修改数据源的操作!当执行
container.B.DeleteObject(b)
命令的时候,a.B这个集合实际上已经被修改了,所以会收到报错。那么换一个思路,用回for循环:
1 | for (int i = 0; i < a.B.Count; i++) |
特别需要注意这里会犯一个错误,虽然使用了for循环,但是该操作仍然是一个修改数据源的操作,也就是说每当执行一个
container.B.DeleteObject(b);
a.B.Count是减少一个的,所以代码应该是
1 | for (int i = 0; i < a.B.Count; i++) |
所以说细节决定成败,这种很容易犯的小错误以后还是需要注意啊:(
3.级联删除
首先需要在EF模型中建立级联删除关系
然后将A与B都读取到DataContext中,再删除主表A,EF就会级联的删除与A相关联的所有的B。
EF一对多关系删除问题