-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EF Core 6 - IsTemporal adds an unnecessary migration when DefaultSchema is configured at the DbContext Level #26676
Comments
@maumar Repros on 7.0.0-alpha.1.21566.3 daily build. Servicing consider. |
Problem here is that when we build RelationalModel in design time, when we create annotations for table we assign HistoryTableSchema the same as the table schema, if the history table schema wasn't set explicitly (so that table schema and history table schema are in sync). This becomes a problem, when the model differ looks at that RelationalModel and compares it with current model (where history table is not set) and hence generates the migration. When building actual migration sql we compensate for the difference and not generate actual sql code, but the problem persists. We can fix this by leaving historytableschema as null if it wasn't explicitly set, so that the RelationalModel is the same as current model. However this complicates the migration generation step - now we need to sometimes generate extra migrations, because differ won't detect it. e.g.: myEntity.ToTable("MyTable", "mySchema", tb => tb.IsTemporal()) changed to: myEntity.ToTable("MyTable", "myModifiedSchema", tb => tb.IsTemporal()) model differ will only detect change in the table schema but we also need to change schema of the history table. This gets worse if you, say, also change the history table name - the differ doesn't know that the history table schema would be implicitly changed (when the temporal table schema changed), so it generates migration with potentially incorrect schema and we need to correct this. There are probably more issues around this so we need to add a lot of tests to make sure we don't regress - too risky to patch especially given that there is a simple (but annoying) workaround. Alternatively we can try a different approach - maybe make it so that in current model, history table schema also follows the table schema, So we avoid the differ discrepancy between relational model and current model, but we don't get the complications mentioned above. But we get into business of managing conventions - when schema changes on entity or global schema is added, we need to propagate the change to history tables. |
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to improve the temporal convention so that history table schema in current model (more) closely resembles the temporal table schema and therefore is similar to RelationalModel generated in runtime. Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to improve the temporal convention so that history table schema in current model (more) closely resembles the temporal table schema and therefore is similar to RelationalModel generated in runtime. Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to improve the temporal convention so that history table schema in current model (more) closely resembles the temporal table schema and therefore is similar to RelationalModel generated in runtime. Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to improve the temporal convention so that history table schema in current model (more) closely resembles the temporal table schema and therefore is similar to RelationalModel generated in runtime. Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to improve the temporal convention so that history table schema in current model (more) closely resembles the temporal table schema and therefore is similar to RelationalModel generated in runtime. Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to add missing default annotations in the model finalization step. This is a temporary measure until we implement default value conventions (#9329) Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to add missing default annotations in the model finalization step. This is a temporary measure until we implement default value conventions (#9329) Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to add missing default annotations in the model finalization step. This is a temporary measure until we implement default value conventions (#9329) Fixes #26676
…when DefaultSchema is configured at the DbContext Level Problem was a discrepancy between RelationalModel build in runtime and the current model (from OnModelCreating) - relational model would set history table schema annotation using the table schema or default schema, however current model wouldn't set those annotations. Model differ would then pick up on those differences and create migration to set the schema for history table. When building actual migration sql we already compensated for the difference and not generate actual sql code, but the problem persists. Fix is to add missing default annotations in the model finalization step. This is a temporary measure until we implement default value conventions (#9329) Fixes #26676
This did the trick for me .ToTable(b => b.IsTemporal(tb => tb.UseHistoryTable(b.Name!, b.Schema!))); |
I am seeing this incorrect behavior with EF Core 6 in relation to TemporalTables.
Consider the below code.
Now to reproduce the issue,
Look at the highlighted line. It drops the annotation for the schema in History table.
I can get around this issue by removing the DefaultSchema configuration from the DbCotext level and introducing it into the table level. But then that has to be done for each table :(
The sample executable code is attached herewith.
EfCore6-TemporalTables.zip
Environment Info:
The text was updated successfully, but these errors were encountered: