-
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
Migration fails when adding a check constraint on a second owned entity #23399
Comments
I made a hacky workaround by overriding [SuppressMessage("Usage", "EF1001:Internal EF Core API usage.")]
public sealed class CustomMigrationsModelDiffer : MigrationsModelDiffer
{
private static readonly FieldInfo _entityTypeField = typeof(CheckConstraint)
.GetField("<EntityType>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
private static void FixModel(IRelationalModel? relationalModel)
{
if (relationalModel is null)
return;
foreach (var table in relationalModel.Tables)
{
foreach (var mapping in table.EntityTypeMappings)
{
foreach (var checkConstraint in CheckConstraint.GetCheckConstraints(mapping.EntityType))
_entityTypeField.SetValue(checkConstraint, mapping.EntityType);
}
}
}
public CustomMigrationsModelDiffer(
IRelationalTypeMappingSource typeMappingSource,
IMigrationsAnnotationProvider migrationsAnnotations,
IChangeDetector changeDetector,
IUpdateAdapterFactory updateAdapterFactory,
CommandBatchPreparerDependencies commandBatchPreparerDependencies) : base(
typeMappingSource,
migrationsAnnotations,
changeDetector,
updateAdapterFactory,
commandBatchPreparerDependencies)
{
}
protected override IEnumerable<MigrationOperation> Diff(IRelationalModel? source, IRelationalModel? target, DiffContext diffContext)
{
FixModel(source);
FixModel(target);
return base.Diff(source, target, diffContext);
}
} It seems that inside |
@AndriySvyryd Looks like this could be a model building bug when using CheckConstraint on an owned type. /cc @bricelam |
@Neme12 Thanks for all the details and the debugging! The issue is that the second check constraint keeps a stale reference to the entity type after the owned entity type is converted to an entity type with defined navigation. As a workaround add the owned types before configuring them: modelBuilder.Entity<Portal>().OwnsOne(x => x.Created);
modelBuilder.Entity<Portal>().OwnsOne(x => x.Updated);
modelBuilder.Entity<Portal>().OwnsOne(x => x.Created, action =>
{
action.HasCheckConstraint("Created_Foo", "[UserId] >= 0");
});
modelBuilder.Entity<Portal>().OwnsOne(x => x.Updated, action =>
{
action.HasCheckConstraint("Updated_Foo", "[UserId] >= 0");
}); |
We discussed this in triage and based on the reasonable workaround and that the fix may require new API surface we are not currently planning to patch this for 5.0. We could revisit this with more feedback. |
@AndriySvyryd Thanks for the workaround, but I'll probably stay with the one I put above - even though it's a lot hackier, it's universal and we already use owned entities and check constraints a lot. I actually copied the extension methods from the PR that added the ability to add check constraints on owned entities: https://github.com/dotnet/efcore/pull/20632/files#diff-a56b326c639183f70932d8d8650e727f into my EF Core 3.1 project and it worked perfectly until upgrading to EF Core 5 - I guess it stopped working because of some of the other changes made to owned entity types in 5.0. @ajcvickers I understand that this cannot be considered a regression because this wasn't provided in-box with 3.1, but since it worked before just I'm curious why the fix requires a new API surface? |
@Neme12 The fix requires API changes compared to 5.0 because the metadata for check constraints changed. |
How does this even happen? When the ability to add check constraints to owned entities was added, were there no tests added with just more than 1 check constraint? 😕 |
Steps to reproduce
Add-Migration Initial
HasCheckConstraint
callAdd-Migration Second
An exception is thrown and the migration cannot be created:
Verbose output from
dotnet ef migrations add Second --verbose
:Include provider and version information
EF Core version: 5.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 5.0
Operating system: Windows 10 Version 1909
IDE: Visual Studio 16.9.0 Preview 1.0
The text was updated successfully, but these errors were encountered: