Using StoreGeneratedPattern.Identity with database-trigger-generated primarykey values not possible?

血红的双手。 提交于 2019-12-12 15:43:30

问题


This question is related to another question i asked here ( Entity Framework 4.2 - How to realize TPT-Inheritance with Database-generated Primarykey Value? ) and should simply clarify, if my assumptions, regarding the problem stated in the topic, are right or not.

The Problem (in detail):

  • I want to use EF (4.1) to access a database, that already exists
  • the database has some restrictions regarding the generation of primary key values for its tables (there is a UDF that takes a tablename and returns the next available ID)
  • To make things as easy as possible for myself, my first approach was to define database triggers (before insert) that call the ID-generating UDF to set the new ID on inserting a new datarow
  • Then i set the StoreGeneratedPattern properties of the corresponding entities in the csdl of my EDM to "Identity", so that the newly generated IDs would be set in the entity objects after saving them to the DB

The Result of this was:

When I created a new entity object, added it to the DbContext and called SaveChanges on it, the corresponding datarow was inserted in the database, but the entity was not updated with the new database-generated ID. I realized this when i tried to save more at once, that have associations to each other (parent-child), because the foreignkey properties of the child entities could not be set correctly, since the new ID of the parent was not known to the DbContext.

This is the reason I asked the above mentioned question concerning TPT inheritance.

After several days of research and trying everything that came to my mind to solve this problem, i think i realized, that this simply cannot work. Although the documentation of the StoreGeneratedPattern enum at MSDN and several explanations in blogs suggests, that StoreGeneratedPattern.Identity should be set to retrieve the generated value, when the DB generates a value on inserting a new row, this is not true for primary keys in conjunction with database triggers.

After thinking about that a long time, that seems perfectly logical to me, since the EF needs some criterium to retrieve database-generated values, and i think that would be in most cases the identity of an entity. For databasecolumns that are set to autoincrement (or identity-column, ...) that might be no problem, because the DBMS provides some functionality to retrieve the last inserted identity-value (e.g. @@identity in MSSQL). But when using a trigger to generate a new identity-value, the EF obviously doesnt know how to query the newly inserted row (and i cant imagine any good db-independent way to do this either).

So my actual question is: are the assumptions above correct or am I overlooking something important here?

Thanks in advance for any clarification/inspiration on this.

Edit (followup question):

After reading the answer from Ladislav another question arises:

If I set StoreGeneratedPattern in CSDL, do I have to set it to the same value in SSDL (and vice versa)? The patch for the edm designer implies that this is the case, because it automatically synchronizes the StoreGeneratedPattern in SSDL when you change it in CSDL (through the designer).


回答1:


The StoreGeneratedPattern.Identity should work. If you set it in EF Designer make sure that it was correctly configured in both SSDL and CSDL parts of EDMX file (open it as XML to check it). There was a bug in EF designer which caused correct setting only in CSDL so SQL part didn't know that new ID must be selected from the database after insert. This bug was in some rare cases solved by installing VS 2010 SP1 and it should be definitely solved by special patch.




回答2:


I had the same problem: one of the column was set with trigger.

But it appeared that I did have troubles with VS edmx designer ('Identity' hadn't been set), and it helped fix it manually (one model had correct value, but other didn't).

Then we got "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries". That was easily fixed following instuctions here

If I set StoreGeneratedPattern in CSDL, do I have to set it to the same value in SSDL (and vice versa)?

Yes, it seems to not work without changes to both CSDL and SSDL



来源:https://stackoverflow.com/questions/8645510/using-storegeneratedpattern-identity-with-database-trigger-generated-primarykey

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