1

我想在以下场景中使用 EF (4.2):

  • 已经存在一个数据库(所以我选择了数据库优先的方法),它是一个 SQL Anywhere 数据库。
  • 我想使用持久性无知的业务对象,所以我使用模板从 EDMDbContext生成类。POCO
  • 我的实体之间有一个简单的继承层次结构:一个抽象的基础实体和两个具体的派生实体。
  • 在数据库中,每种类型的继承层次都有一个表(Table-Per-Type Strategy)。
  • 这三个表中的每一个都有一个主键列 ( Id, type: integer),具体实体与基本实体的关联是通过Id在两个表中具有相同的来完成的(这意味着Id具体类型表的主键 ( )同时是基表的外键;我认为这是一种非常常见的方法)。

我必须在设计器中手动定义继承,因为 EDM 助手不会自动识别,即希望在所描述的实体之间具有继承关联。

到此为止,没有任何更大的问题。现在到手头的问题:我使用的数据库有一个限制:Primarykey值必须由数据库生成,使用数据库函数。我想before-insert-triggerbase-table.

为了让实体框架知道一个值是由数据库生成的,我设置了toStoreGeneratedPatternIdProperty的属性(据我了解,这是在插入新的实体实例后告诉EF获取生成的值的方式)。base-entityIdentity

当我创建派生实体的新实例时,将其添加到上下文的对应并调用时,会抛出 a DbSetDbContext说明违反了约束。通过检查数据库的请求日志,我看到基本实体被插入到基表中,但是在派生表中插入行时,出现上述错误,因为它显然没有使用新生成的基表中的新条目。SaveChangesDbUpdateExceptionforeignkeyId

由于我认为在数据库级别上对此我无能为力,因此问题是,是否可以配置(或修改)EDM 或 DbContext 以首先插入基本行,然后获取生成的Id并将其用于插入派生行。

我知道有几种方法可以避免这种情况(不使用继承,使用存储过程插入新的派生实体,在插入之前调用生成 id 的 db 函数并Id自己在实体上设置属性),但目前上述行为将是最可取的,所以我想确保在决定任何“B计划”之前不要忽视某些事情。

非常感谢有关此主题的任何建议,在此先感谢。

这是触发器的代码:

ALTER TRIGGER "TRG_GENERATE_ID" before insert order 1 on
BASE_TABLE
referencing new as NewEntry
for each row
begin
  declare NewID integer;
  set NewID = F_GET_NEW_ID('BASE_TABLE', NewEntry.SOME_OTHER_ID);
  set NewEntry.ID = NewID
end

在触发器中调用函数“F_GET_NEW_ID”来为基表中的新条目生成新 ID。它有两个参数:"Tablename" -> 应该为其生成新ID的表的名称,第二个参数取数据库所有表中标准列的值(生成新ID是必需的) )。

4

0 回答 0