实体框架4.2 - 如何使用数据库生成的主键值实现TPT继承?

时间:2011-12-14 20:06:48

标签: entity-framework-4.1 identity dbcontext table-per-type

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

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

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

在此之前没有任何更大的问题。现在到手头的问题: 我使用的数据库有一个限制:数据库必须使用数据库函数生成Id值。 我想在Primarykey上定义的before-insert-trigger中调用此函数。

为了让实体框架知道数据库生成了一个值,我将base-table的{​​{1}}属性的StoreGeneratedPattern属性设置为Id(As我明白了,这是告诉EF在插入实体的新实例后获取生成的值的方法。

当我创建派生实体的新实例时,将其添加到base-entity的相应Identity并在上下文中调用DbSet,抛出DbContext ,声明违反了SaveChanges约束。 通过检查数据库的请求日志,我看到基本实体已插入基表中,但是在派生表中插入行时,会出现上述错误,因为它显然不会使用新生成的{基表中新条目的{1}}。

由于我不认为我可以在数据库级别上做很多事情,所以问题是,如果可以配置(或修改)EDM或DbContext以首先插入基行,那么采取生成的{ {1}}并使用它来插入派生行。

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

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

以下是触发器的代码:

foreignkey

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

0 个答案:

没有答案