Skip to content
Merged
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 @@ -14,8 +14,11 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Design.Internal;
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
#pragma warning disable EF1001 // Internal EF Core API usage.
public class NpgsqlCSharpRuntimeAnnotationCodeGenerator : RelationalCSharpRuntimeAnnotationCodeGenerator
public class NpgsqlCSharpRuntimeAnnotationCodeGenerator
: RelationalCSharpRuntimeAnnotationCodeGenerator, ICSharpRuntimeAnnotationCodeGenerator
{
private int _typeMappingNestingCount;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -42,8 +45,31 @@ public override bool Create(
ValueComparer? keyValueComparer = null,
ValueComparer? providerValueComparer = null)
{
var result = base.Create(typeMapping, parameters, valueComparer, keyValueComparer, providerValueComparer);
_typeMappingNestingCount++;

try
{
var result = base.Create(typeMapping, parameters, valueComparer, keyValueComparer, providerValueComparer);
AddNpgsqlTypeMappingTweaks(typeMapping, parameters);
return result;
}
finally
{
_typeMappingNestingCount--;
}
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[EntityFrameworkInternal]
protected virtual void AddNpgsqlTypeMappingTweaks(
CoreTypeMapping typeMapping,
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var mainBuilder = parameters.MainBuilder;

var npgsqlDbTypeBasedDefaultInstance = typeMapping switch
Expand All @@ -57,6 +83,8 @@ public override bool Create(

if (npgsqlDbTypeBasedDefaultInstance is not null)
{
CheckElementTypeMapping();

var npgsqlDbType = ((INpgsqlTypeMapping)typeMapping).NpgsqlDbType;

if (npgsqlDbType != npgsqlDbTypeBasedDefaultInstance.NpgsqlDbType)
Expand All @@ -83,6 +111,8 @@ public override bool Create(
switch (typeMapping)
{
case NpgsqlEnumTypeMapping enumTypeMapping:
CheckElementTypeMapping();

var code = Dependencies.CSharpHelper;
mainBuilder.AppendLine(";");

Expand Down Expand Up @@ -119,6 +149,8 @@ public override bool Create(

case NpgsqlRangeTypeMapping rangeTypeMapping:
{
CheckElementTypeMapping();

var defaultInstance = NpgsqlRangeTypeMapping.Default;

var npgsqlDbTypeDifferent = rangeTypeMapping.NpgsqlDbType != defaultInstance.NpgsqlDbType;
Expand Down Expand Up @@ -154,7 +186,14 @@ public override bool Create(
}
}

return result;
void CheckElementTypeMapping()
{
if (_typeMappingNestingCount > 1)
{
throw new NotSupportedException(
$"Non-default Npgsql type mappings ('{typeMapping.GetType().Name}' with store type '{(typeMapping as RelationalTypeMapping)?.StoreType}') aren't currently supported as element type mappings, see https://github.com/npgsql/efcore.pg/issues/3366.");
}
}
}

/// <inheritdoc />
Expand Down