Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -703,20 +703,6 @@ protected virtual void GenerateComplexPropertyAnnotations(
.FilterIgnoredAnnotations(property.ComplexType.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

// Add ContainerColumnType annotation if complex type is mapped to JSON but the type annotation is missing
if (typeAnnotations.ContainsKey(RelationalAnnotationNames.ContainerColumnName)
&& !typeAnnotations.ContainsKey(RelationalAnnotationNames.ContainerColumnType))
{
var containerColumnType = property.ComplexType.GetContainerColumnType()
?? Dependencies.RelationalTypeMappingSource.FindMapping(typeof(JsonTypePlaceholder))?.StoreType;
if (containerColumnType != null)
{
typeAnnotations[RelationalAnnotationNames.ContainerColumnType] = new Annotation(
RelationalAnnotationNames.ContainerColumnType,
containerColumnType);
}
}

GenerateAnnotations(
propertyBuilderName, property, stringBuilder, propertyAnnotations,
inChainedCall: false, hasAnnotationMethodInfo: HasPropertyAnnotationMethodInfo);
Expand Down Expand Up @@ -917,20 +903,6 @@ protected virtual void GenerateEntityTypeAnnotations(
.FilterIgnoredAnnotations(entityType.GetAnnotations())
.ToDictionary(a => a.Name, a => a);

// Add ContainerColumnType annotation if entity is mapped to JSON but the type annotation is missing
if (annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnName)
&& !annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnType))
{
var containerColumnType = entityType.GetContainerColumnType()
?? Dependencies.RelationalTypeMappingSource.FindMapping(typeof(JsonTypePlaceholder))?.StoreType;
if (containerColumnType != null)
{
annotations[RelationalAnnotationNames.ContainerColumnType] = new Annotation(
RelationalAnnotationNames.ContainerColumnType,
containerColumnType);
}
}

GenerateTableMapping(entityTypeBuilderName, entityType, stringBuilder, annotations);
GenerateSplitTableMapping(entityTypeBuilderName, entityType, stringBuilder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,18 @@ public virtual void ProcessModelFinalizing(
IConventionModelBuilder modelBuilder,
IConventionContext<IConventionModelBuilder> context)
{
var defaultJsonStoreType =
Comment thread
AndriySvyryd marked this conversation as resolved.
Outdated
((RelationalTypeMapping?)Dependencies.TypeMappingSource.FindMapping(typeof(JsonTypePlaceholder)))?.StoreType;

foreach (var jsonEntityType in modelBuilder.Metadata.GetEntityTypes().Where(e => e.IsMappedToJson()))
{
if (defaultJsonStoreType != null
&& jsonEntityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName)?.Value is string
&& jsonEntityType.FindAnnotation(RelationalAnnotationNames.ContainerColumnType) == null)
{
jsonEntityType.SetContainerColumnType(defaultJsonStoreType);
}

foreach (var enumProperty in jsonEntityType
.GetDeclaredProperties()
.Where(p => p.ClrType.UnwrapNullableType().IsEnum))
Expand All @@ -67,5 +77,30 @@ public virtual void ProcessModelFinalizing(
}
}
}

if (defaultJsonStoreType != null)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
SetDefaultContainerColumnTypeForComplexTypes(entityType, defaultJsonStoreType);
}
}
}

private static void SetDefaultContainerColumnTypeForComplexTypes(
IConventionTypeBase typeBase,
string defaultJsonStoreType)
{
foreach (var complexProperty in typeBase.GetComplexProperties())
{
var complexType = complexProperty.ComplexType;
if (complexType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName)?.Value is string
&& complexType.FindAnnotation(RelationalAnnotationNames.ContainerColumnType) == null)
{
complexType.SetContainerColumnType(defaultJsonStoreType);
}

SetDefaultContainerColumnTypeForComplexTypes(complexType, defaultJsonStoreType);
}
}
}
54 changes: 54 additions & 0 deletions test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3053,6 +3053,60 @@ public void Complex_collection_container_column_type_is_used_in_relational_model
Assert.Equal("some_json_mapping", column.StoreType);
}

[ConditionalFact]
public void Complex_property_gets_default_container_column_type_when_not_set_explicitly()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<EntityWithComplexProperty>(eb =>
{
eb.ComplexProperty(
e => e.ComplexProperty, cb =>
{
cb.ToJson("complex_data");
});
});

var model = Finalize(modelBuilder);

var entityType = model.Model.FindEntityType(typeof(EntityWithComplexProperty));
var complexProperty = entityType.GetComplexProperties().Single();
var complexType = complexProperty.ComplexType;

Assert.Equal("some_json_mapping", complexType.GetContainerColumnType());

var table = entityType.GetTableMappings().Single().Table;
var column = table.Columns.Single(c => c.Name == "complex_data");
Assert.Equal("some_json_mapping", column.StoreType);
}

[ConditionalFact]
public void Complex_collection_gets_default_container_column_type_when_not_set_explicitly()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<EntityWithComplexCollection>(eb =>
{
eb.ComplexCollection(
e => e.ComplexCollection, cb =>
{
cb.ToJson("collection_data");
});
});

var model = Finalize(modelBuilder);

var entityType = model.Model.FindEntityType(typeof(EntityWithComplexCollection));
var complexProperty = entityType.GetComplexProperties().Single();
var complexType = complexProperty.ComplexType;

Assert.Equal("some_json_mapping", complexType.GetContainerColumnType());

var table = entityType.GetTableMappings().Single().Table;
var column = table.Columns.Single(c => c.Name == "collection_data");
Assert.Equal("some_json_mapping", column.StoreType);
}

[ConditionalFact]
public void Can_use_relational_model_with_functions()
{
Expand Down
Loading