为什么调用EntityCollection.Remove()会导致SaveChanges()抛出InvalidOperationException异常?

4

以下是数据库架构:

CREATE TABLE master (
    id integer primary key autoincrement, 
    title text);
CREATE TABLE slave (
    id integer primary key autoincrement, 
    master_id integer not null, 
    title text, 
    foreign key (master_id) references master (id));

我创建了一个sqlite数据库,然后使用它来创建一个Entity Framework的.edmx文件。 接着我添加了一条主记录和一条从记录,这个操作很顺利。但是当我尝试删除从记录时,却出现了异常,我不知道为什么。请注意保留HTML标记。
var ctx = new blaEntities();
var newMaster = master.Createmaster(0);
ctx.masters.AddObject(newMaster);

var newSlave = slave.Createslave(0, 0);
newMaster.slaves.Add(newSlave);

ctx.SaveChanges(); // works fine, both id and master_id properties of newMaster 
                   // and newSlave are then set with generated values.

newMaster.slaves.Remove(newSlave);

ctx.SaveChanges(); // InvalidOperationException is raised

异常消息为:
操作失败:由于一个或多个外键属性是非空的,因此无法更改关系。当对关系进行更改时,相关的外键属性将设置为 null 值。如果外键不支持 null 值,则必须定义新的关系、分配另一个非 null 值给外键属性,或删除不相关的对象。
我做错了什么?
编辑:
这里是由 EF 生成的 Createslave(...) 方法:
public static slave Createslave(global::System.Int64 id, global::System.Int64 master_id)
{
    slave slave = new slave();
    slave.id = id;
    slave.master_id = master_id;
    return slave;
}
2个回答

1

你的从属仍然存在,他的FK列master_id需要一个值。如果你想完全删除它,你需要告诉EF去删除它,而不是从它的父级中移除它。如果你不想删除它,分配一个新的master_id或将这个列设置为可空。


1

您的从表中仍然存在一个从对象,其masterId列中没有设置值。

尝试使用ctx.DeleteObject(newSlave)来摆脱它。


当我添加从属时,我不需要调用AddObject,但是当我删除它时,我需要调用DeleteObject吗? - user610650
@Ludo 我认为 CreateSlave() 方法已经为您添加了对象,或者说添加到了主对象中。也许他们决定在删除时更加明确会更好?您不希望意外删除刚想分配给其他主对象的东西。 - Botz3000
我不认为它会。我已经更新了我的问题并附上了它的定义。 - user610650
@Ludo,这就是为什么我编辑了我的评论,添加到主分支可能会导致这种情况。不幸的是,我不能再删除CreateSlave部分了。DeleteObject起作用了吗? - Botz3000
是的,似乎你是正确的:不需要使用 AddObject 来插入,但是需要调用 DeleteObject 来删除。更进一步,看起来只有 DeleteObject 是必要的,因为它会从 EntityCollection 中删除该对象。 - user610650

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接