Entity Framework 4.2 - How to realize TPT-Inheritance with Database-generated Primarykey Value?

淺唱寂寞╮ 提交于 2019-12-08 07:53:27

问题


I want to use the EF (4.2) in the following scenario:

  • There exists a database already (so I chose the database-first approach) and it is a SQL Anywhere DB.
  • I want to use persistence-ignorant business objects, so I use the DbContext Template to generate POCO classes from the EDM.
  • There is one simple inheritance hierarchy among my entities: an abstract base entity and two concrete derived entities.
  • In the database there is one table for each type of the inheritance hierarchy (Table-Per-Type Strategy).
  • Each of these three tables has a primary key column (Id, type:integer), and the association of a concrete entity to the base entity is done by having the same Id in both tables (that means that the primary key (Id) of the concrete type tables is at the same time a foreign key to the base table; a pretty common approach I think).

I had to define the Inheritance manually in the designer, since the EDM assistant does not automatically recognize, that is want to have an inheritance association between the described entities.

Until this point there wasn't any bigger problem. Now to the issue at hand: There is a restriction for the database I use: Primarykey values have to be generated by the database, using a database function. I want to call this function in a before-insert-trigger defined on the base-table.

To let the entity framework know that a value is generated by the database, I set the StoreGeneratedPattern property of the Id Property of the base-entity to Identity (As I understood, this is the way to tell EF to get the generated value after inserting a new instance of an entity).

When I create a new instance of a derived entity, add it to the corresponding DbSet of the DbContext and call SaveChanges on the context, a DbUpdateException is thrown, stating that a foreignkey constraint is violated. By checking the request-log of the DB, I see that the base entity got inserted in the base table, but on inserting the row in the derived table, the above mentioned error occurs, because it obviously doesn't use the newly generated Id of the new entry in the base table.

Since I don't think there is much I can do on a database level against that, the question is, if the EDM or DbContext can be configured (or modified) to insert the base row first, then take the generated Id and use it for insertion of the derived row.

I know there are several way to avoid this situation (not using inheritance, using a stored procedure to insert a new derived entity, calling the id-generating db-function before inserting and set the Id property myself on the entity), but at the moment the above-described behavior would be the most preferable, so I want to make sure not to overlook something before deciding for any "plan B".

Any suggestions on this topic are much appreciated, Thanks in advance.

Here is the code of the trigger:

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

The function "F_GET_NEW_ID" is called in the trigger to generate the new ID for a new entry in the base table. It has two parameters: "Tablename" -> The name of the table for which a new ID should be generated, and a second parameter that takes the value of a standardcolumn in all tables of the database (it is required to generate the new ID).

来源:https://stackoverflow.com/questions/8510939/entity-framework-4-2-how-to-realize-tpt-inheritance-with-database-generated-pr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!