Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,7 @@ protected virtual void GenerateComplexPropertyAnnotations(
if (typeAnnotations.ContainsKey(RelationalAnnotationNames.ContainerColumnName)
&& !typeAnnotations.ContainsKey(RelationalAnnotationNames.ContainerColumnType))
{
var containerColumnType = property.ComplexType.GetContainerColumnType()
?? Dependencies.RelationalTypeMappingSource.FindMapping(typeof(JsonTypePlaceholder))?.StoreType;
var containerColumnType = property.ComplexType.GetContainerColumnType();
if (containerColumnType != null)
{
typeAnnotations[RelationalAnnotationNames.ContainerColumnType] = new Annotation(
Expand Down Expand Up @@ -921,8 +920,7 @@ protected virtual void GenerateEntityTypeAnnotations(
if (annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnName)
&& !annotations.ContainsKey(RelationalAnnotationNames.ContainerColumnType))
{
var containerColumnType = entityType.GetContainerColumnType()
?? Dependencies.RelationalTypeMappingSource.FindMapping(typeof(JsonTypePlaceholder))?.StoreType;
var containerColumnType = entityType.GetContainerColumnType();
if (containerColumnType != null)
{
annotations[RelationalAnnotationNames.ContainerColumnType] = new Annotation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

// ReSharper disable once CheckNamespace
#pragma warning disable IDE0130 // Namespace does not match folder structure
Expand Down Expand Up @@ -416,11 +417,32 @@ public static void SetContainerColumnName(this IMutableTypeBase typeBase, string
/// <param name="typeBase">The type.</param>
/// <returns>The database column type.</returns>
public static string? GetContainerColumnType(this IReadOnlyTypeBase typeBase)
=> typeBase.FindAnnotation(RelationalAnnotationNames.ContainerColumnType)?.Value is string columnName
? columnName
: typeBase is IReadOnlyEntityType entityType
? entityType.FindOwnership()?.PrincipalEntityType.GetContainerColumnType()
: ((IReadOnlyComplexType)typeBase).ComplexProperty.DeclaringType.GetContainerColumnType();
{
if (typeBase.FindAnnotation(RelationalAnnotationNames.ContainerColumnType)?.Value is string columnType)
{
return columnType;
}

var parentType = typeBase is IReadOnlyEntityType entityType
? entityType.FindOwnership()?.PrincipalEntityType.GetContainerColumnType()
: ((IReadOnlyComplexType)typeBase).ComplexProperty.DeclaringType.GetContainerColumnType();

if (parentType != null)
{
return parentType;
}

if (typeBase.IsMappedToJson()
#pragma warning disable EF1001 // Internal EF Core API usage.
&& (typeBase.Model is not Model model || model.IsReadOnly))
#pragma warning restore EF1001 // Internal EF Core API usage.
{
return ((IRelationalTypeMappingSource)((IModel)typeBase.Model).GetModelDependencies().TypeMappingSource)
.FindMapping(typeof(JsonTypePlaceholder))?.StoreType;
}

return null;
}

/// <summary>
/// Sets the type of the container column to which the type is mapped.
Expand Down
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