在EF6中插入嵌套集合时违反外键(数据库优先)

时间:2018-07-31 20:15:47

标签: asp.net entity-framework-6 foreign-keys

我在使用Identifying Relationships

的数据库优先项目中有一个嵌套集合

例如(仅显示主实体键):

+--Quotes--+          +------State-----+           +---State Info---+
|ID (int)  | -(1-*)-> | Quote_ID (int) |  -(1-*)-> | Quote_ID (int) |
+----------+          | State_ID (int) |           | State_ID (int) |
                      +----------------+           | Info_ID (int)  |
                                                   +----------------+

请注意,在第一个关联中,这是一对多的关联,其中Quotes.ID-> Quote_ID。 第二个关联是一对多组合键,其主键是Quote_ID / State_ID。

现在,假设Quote已经存在(作为The Quote),并且我要添加一个新状态:

theQuote.States.add(new State with {.State_ID=5})

现在我要添加一个新的状态信息:

StateObj.StateInfos.add(New StateInfo with {.Info_ID=38})

现在,我连接一个SQL事件探查器并将其保存:

db.SaveChanges()

正在发生的事情是我看到两个插入物:

exec sp_executesql N'INSERT [dbo].[States]([Quote_ID], [State_ID])
VALUES (@0, @1)',@0=153888,@1=5

exec sp_executesql N'INSERT [dbo].[StateInfo]([Quote_ID],[State_ID],[Info_ID])
values (@0, @1, @2)',@0=0,@1=0,@2=38

请注意,在第一个插入(子集合)中,EF会理解该关系并自动插入正确的quote_id。但是,在第二个插入(孙子集合)中,它无法正确同步关联,并且不知道正确的值。这将导致不幸的“ Insert语句与FOREIGN KEY约束冲突……” SQL错误。

现在,如果StateObj已经存在并且我仅插入StateInfo,则此方案可以正常工作。我需要能够同时插入State和StateInfo。

似乎是对EF6的合理要求,但是由于某些原因,我无法使它正常工作。我尝试将实体键的StoreGeneratedPattern属性更改为“ Identity”,但无济于事。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我有一个理由为什么会这样。显然,我有一个overlapping key

我介绍的表格模型不完整。我还有一个显然引起问题的关联:

+--Quotes--+          +------State-----+           +---State Info---+
|ID (int)  | -(1-*)-> | Quote_ID (int) |  -(1-*)-> | Quote_ID (int) |
+----------+          | State_ID (int) |           | State_ID (int) |
                      | StateView (nav)|           | Info_ID (int)  |
                      +----------------+           +----------------+
                              ^                    
             +-StateView-+    | (1-*)
             | ID (int)  |----+
             +-----------+

该关联使用StateView.ID作为主键和State.State_ID作为外键。如果删除了此关系,则db.savechanges会按预期工作。

或者,代替使用

theQuote.States.add(new State with {.State_ID=5})

执行此操作:

dim StateViewObj as StateView=db.StateView.Find(5)
theQuote.States.add(new State with {.StateView=StateViewObj})

这似乎可行。

相关问题