-
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
Optimized model no longer using correct schemas in EF 8.0.0 #32739
Comments
/cc @AndriySvyryd |
EF 8 now also stores the relational model that contains all of the database mapping information in the compiled model. You can fallback to computing just the relational model as it was for EF 7 by removing the Also, you don't need to override public partial class DatabaseContextModel
{
private string DefaultSchema { get; init; } = "dbo";
partial void Customize()
{
if (DefaultSchema == "dbo")
return;
RemoveAnnotation("Relational:DefaultSchema");
AddAnnotation("Relational:DefaultSchema", DefaultSchema);
RemoveRuntimeAnnotation("Relational:RelationalModel");
foreach (RuntimeEntityType entityType in ((IModel)this).GetEntityTypes())
Customize(entityType);
}
private void Customize(RuntimeEntityType entityType)
{
// Can't specify schema for shared CLR types
if (((IReadOnlyTypeBase)entityType).HasSharedClrType)
return;
var tableName = entityType.FindAnnotation("Relational:TableName")?.Value as string;
if (string.IsNullOrEmpty(tableName))
return;
var isTenant = SchemaUtils.IsTenantSchema(tableName);
if (!isTenant)
return;
entityType.RemoveAnnotation("Relational:Schema");
entityType.AddAnnotation("Relational:Schema", DefaultSchema);
}
} |
Thank you so much for your support @AndriySvyryd ! It's a shame that the relational model optimization won't work for our multi-schema use case. Is that a hard limitation, or something that may eventually be supported? My database has hundreds of relational constraints and would likely benefit from this. I've removed the When I attempted to remove the runtime annotation in Customize() I ended up with a separate error related to duplicate runtime annotations:
GetEntityTypes() works great, but I did need to cast the entities back to RuntimeEntityType: public partial class DatabaseContextModel
{
private string DefaultSchema { get; init; } = "dbo";
partial void Customize()
{
if (DefaultSchema == SchemaUtils.VERTEX_SCHEMA)
return;
RemoveAnnotation("Relational:DefaultSchema");
AddAnnotation("Relational:DefaultSchema", DefaultSchema);
foreach (var entityType in ((IModel)this).GetEntityTypes().Cast<RuntimeEntityType>())
Customize(entityType);
}
private void Customize(RuntimeEntityType entityType)
{
// Can't specify schema for shared CLR types
if (((IReadOnlyTypeBase)entityType).HasSharedClrType)
return;
var tableName = entityType.FindAnnotation("Relational:TableName")?.Value as string;
if (string.IsNullOrEmpty(tableName))
return;
var isTenant = SchemaUtils.IsTenantSchema(tableName);
if (!isTenant)
return;
entityType.RemoveAnnotation("Relational:Schema");
entityType.AddAnnotation("Relational:Schema", DefaultSchema);
}
} |
The current implementation of the relational model is read-only, however #20284 would allow it to be mutated.
If startup time is critical for your application and you don't change the model often you could write a script that modifies the code that we generate for
We can fix this for 9.0 |
EF Core version: 8.0.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: .NET 8.0
Operating system: Windows 10
IDE: Visual Studio 2022 17.8.0
Hello!
I've been using Optimized Models in EF7 with great success.
My database model shards tenants at the schema level, so I'll have common tables in the
dbo
schema, and tenant tables in thetenant_xyz
schema. My optimized model partial does the following to make this work:Since upgrading to EF 8 it looks like my DbContext no longer uses the appropriate schema for tenant tables, and is instead looking in dbo for everything.
I've debugged the resulting model and it looks like all of the annotations are correct.
When I remove the DbContextOptionsBuilder UseModel call my context works just fine, albeit slower.
How can I ensure that optimized models in EF 8 are using the appropriate schemas per table?
The text was updated successfully, but these errors were encountered: