Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架中的级联删除(每个类型继承的表)_C#_.net_Entity Framework - Fatal编程技术网

C# 实体框架中的级联删除(每个类型继承的表)

C# 实体框架中的级联删除(每个类型继承的表),c#,.net,entity-framework,C#,.net,Entity Framework,我有一个DB模型,每个类型继承一个表。 例如,实体是A、B、C、A1、A2。 基地-A 导出-A1,A2。 另一个-B,C。 因此,A与A1和A2有1:1的关联。 B和C分别与A1和A2有关联(1到多,在DB端有OnDelete操作) 问题 我试图从B中删除记录,所以我希望EF也会删除与当前B记录关联的所有A1对象 最后,EF从B中删除记录,并从A1中删除所有相关记录,但不从A中删除 为什么??如何修复它?这是一个已知的问题,我称之为bug。显然,仅从表A1中删除派生实体属性的记录是不正确的。数

我有一个DB模型,每个类型继承一个表。 例如,实体是A、B、C、A1、A2。 基地-A 导出-A1,A2。 另一个-B,C。 因此,A与A1和A2有1:1的关联。 B和C分别与A1和A2有关联(1到多,在DB端有OnDelete操作)

问题

我试图从B中删除记录,所以我希望EF也会删除与当前B记录关联的所有A1对象

最后,EF从B中删除记录,并从A1中删除所有相关记录,但不从A中删除


为什么??如何修复它?

这是一个已知的问题,我称之为bug。显然,仅从表
A1
中删除派生实体属性的记录是不正确的。数据库中的其余数据(在表
A
中)表示另一种对象类型。换句话说:这个删除实际上并没有删除一个实体,但它改变了实体的类型=将
A1
类型的对象转换为
A
类型的对象-如果
A
是一个抽象实体,这就更没有意义了

据我所知,推荐的解决方法是:

context.As.Remove(a1)
应同时从
A
A1
表中删除,从而解决表
A
中孤立记录的问题。不幸的是,您被迫从数据库加载子项以正确删除父项


下面是关于这个问题的另一个问题和答案:

我也遇到了同样的问题,一位同事告诉我在执行删除(o)之前要迭代项目集合,但突然一切都起了作用。

有什么建议吗?我觉得这是个小问题。谢谢!微软的团队知道这个错误吗?:)你知道什么时候能修好吗?因为这种方法非常丑陋。但它是有效的:)@user861108:不,我不知道它是否或何时会被修复。我甚至不知道MS是否认为这个问题是一个bug。我认为在这些情况下,如果使用另一种类型的继承,一切都可以。我使用表每类型继承。也许如果我将使用每个层次的表,这个问题就不会出现。你觉得怎么样?@user861108:是的,我很确定TPH继承的问题消失了。这确实是TPT特有的。但TPH还有其他缺陷,比如将所有属性混合到一个表中,在需要派生实体的属性的地方有可为空的列,等等。我可能更喜欢使用上面的解决方法。顺便问一下:当您删除
foreach
循环时,您能测试上面的代码是否仍然有效吗?我知道如果将子项加载到上下文中,EF会发送单独的DELETE语句(在这里使用
Include
)。也许这些删除也会从表
A
中删除行。我已经做了(删除
foreach
循环)。和EF抛出InvalidOperationException:操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
var b = context.Bs.Include("A1s").Single(b => b.Id == 1);
foreach (var a1 in b.A1s.ToList())
    context.As.Remove(a1);
context.Bs.Remove(b);
context.SaveChanges();