Skip to content

Commit

Permalink
Fix to #29297 - Seeding issue with JSON columns in EF Core 7 (#32015)
Browse files Browse the repository at this point in the history
Adding validation step when using HasData with entities mapped to JSON, as well as normal entities navigating into JSON.

Fixes #29297
  • Loading branch information
maumar authored Oct 11, 2023
1 parent d2f1631 commit 3a7fc44
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,29 @@ protected virtual void ValidateIndexProperties(
}
}


/// <inheritdoc/>
protected override void ValidateData(IModel model, IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
foreach (var entityType in model.GetEntityTypes())
{
if (entityType.IsMappedToJson() && entityType.GetSeedData().Any())
{
throw new InvalidOperationException(RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(entityType.DisplayName()));
}

foreach (var navigation in entityType.GetNavigations().Where(x => x.ForeignKey.IsOwnership && x.TargetEntityType.IsMappedToJson()))
{
if (entityType.GetSeedData().Any(x => x.TryGetValue(navigation.Name, out var _)))
{
throw new InvalidOperationException(RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(entityType.DisplayName()));
}
}
}

base.ValidateData(model, logger);
}

/// <summary>
/// Validates that the triggers are unambiguously mapped to exactly one table.
/// </summary>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/EFCore.Relational/Properties/RelationalStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@
<data name="FunctionOverrideMismatch" xml:space="preserve">
<value>The property '{propertySpecification}' has specific configuration for the function '{function}', but it isn't mapped to a column on that function return. Remove the specific configuration, or map an entity type that contains this property to '{function}'.</value>
</data>
<data name="HasDataNotSupportedForEntitiesMappedToJson" xml:space="preserve">
<value>Can't use HasData for entity type '{entity}'. HasData is not supported for entities mapped to JSON.</value>
</data>
<data name="IncompatibleTableCommentMismatch" xml:space="preserve">
<value>Cannot use table '{table}' for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and the comment '{comment}' does not match the comment '{otherComment}'.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,55 @@ public void Json_entity_mapped_to_a_table_but_its_parent_is_mapped_to_a_view()
modelBuilder);
}

[ConditionalFact]
public void SeedData_on_json_entity_throws_meaningful_exception()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<ValidatorJsonEntityBasic>(
b =>
{
b.HasData(new { Id = 1, OwnedReference = new { Name = "foo", Number = 1 } });
b.OwnsOne(
x => x.OwnedReference, bb =>
{
bb.ToJson();
bb.Ignore(x => x.NestedCollection);
bb.Ignore(x => x.NestedReference);
});
b.Ignore(x => x.OwnedCollection);
});

VerifyError(
RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(nameof(ValidatorJsonEntityBasic)),
modelBuilder);
}

[ConditionalFact]
public void SeedData_on_entity_with_json_navigation_throws_meaningful_exception()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<ValidatorJsonEntityBasic>(
b =>
{
b.HasData(new { Id = 1 });
b.OwnsMany(
x => x.OwnedCollection, bb =>
{
bb.ToJson();
bb.HasData(
new { Name = "foo", Number = 1 },
new { Name = "bar", Number = 2 });
bb.Ignore(x => x.NestedCollection);
bb.Ignore(x => x.NestedReference);
});
b.Ignore(x => x.OwnedReference);
});

VerifyError(
RelationalStrings.HasDataNotSupportedForEntitiesMappedToJson(nameof(ValidatorJsonOwnedRoot)),
modelBuilder);
}

private class ValidatorJsonEntityBasic
{
public int Id { get; set; }
Expand Down

0 comments on commit 3a7fc44

Please sign in to comment.