Skip to content
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

[automated] Merge branch 'release/8.0' => 'main' #31632

Merged
1 commit merged into from
Sep 5, 2023
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 @@ -71,6 +71,12 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
private CoreTypeMapping? FindCollectionMapping(in TypeMappingInfo mappingInfo)
{
var clrType = mappingInfo.ClrType!;

if (mappingInfo.ElementTypeMapping != null)
{
return null;
}

var elementType = clrType.TryGetSequenceType();
if (elementType == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public InMemoryTypeMappingSource(TypeMappingSourceDependencies dependencies)

if (clrType.IsValueType
|| clrType == typeof(string)
|| clrType == typeof(byte[]))
|| (clrType == typeof(byte[]) && mappingInfo.ElementTypeMapping == null))
{
return new InMemoryTypeMapping(
clrType, jsonValueReaderWriter: jsonValueReaderWriter);
Expand Down
19 changes: 16 additions & 3 deletions src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public RelationalTypeMappingInfo(
int? scale)
{
// Note: Empty string is allowed for store type name because SQLite
_coreTypeMappingInfo = new TypeMappingInfo(null, false, unicode, size, null, precision, scale);
_coreTypeMappingInfo = new TypeMappingInfo(null, null, false, unicode, size, null, precision, scale);
StoreTypeName = storeTypeName;
StoreTypeNameBase = storeTypeNameBase;
IsFixedLength = null;
Expand All @@ -161,6 +161,7 @@ public RelationalTypeMappingInfo(
/// Creates a new instance of <see cref="RelationalTypeMappingInfo" />.
/// </summary>
/// <param name="member">The property or field for which mapping is needed.</param>
/// <param name="elementTypeMapping">The type mapping for elements, if known.</param>
/// <param name="storeTypeName">The provider-specific relational type name for which mapping is needed.</param>
/// <param name="storeTypeNameBase">The provider-specific relational type name, with any facets removed.</param>
/// <param name="unicode">Specifies Unicode or ANSI mapping, or <see langword="null" /> for default.</param>
Expand All @@ -169,14 +170,15 @@ public RelationalTypeMappingInfo(
/// <param name="scale">Specifies a scale for the mapping, or <see langword="null" /> for default.</param>
public RelationalTypeMappingInfo(
MemberInfo member,
RelationalTypeMapping? elementTypeMapping = null,
string? storeTypeName = null,
string? storeTypeNameBase = null,
bool? unicode = null,
int? size = null,
int? precision = null,
int? scale = null)
{
_coreTypeMappingInfo = new TypeMappingInfo(member, unicode, size, precision, scale);
_coreTypeMappingInfo = new TypeMappingInfo(member, elementTypeMapping, unicode, size, precision, scale);

StoreTypeName = storeTypeName;
StoreTypeNameBase = storeTypeNameBase;
Expand Down Expand Up @@ -212,6 +214,7 @@ public RelationalTypeMappingInfo(
/// Creates a new instance of <see cref="TypeMappingInfo" />.
/// </summary>
/// <param name="type">The CLR type in the model for which mapping is needed.</param>
/// <param name="elementTypeMapping">The type mapping for elements, if known.</param>
/// <param name="storeTypeName">The database type name.</param>
/// <param name="storeTypeNameBase">The provider-specific relational type name, with any facets removed.</param>
/// <param name="keyOrIndex">If <see langword="true" />, then a special mapping for a key or index may be returned.</param>
Expand All @@ -224,6 +227,7 @@ public RelationalTypeMappingInfo(
/// <param name="dbType">The suggested <see cref="DbType"/>, or <see langword="null" /> for default.</param>
public RelationalTypeMappingInfo(
Type? type = null,
RelationalTypeMapping? elementTypeMapping = null,
string? storeTypeName = null,
string? storeTypeNameBase = null,
bool keyOrIndex = false,
Expand All @@ -235,7 +239,7 @@ public RelationalTypeMappingInfo(
int? scale = null,
DbType? dbType = null)
{
_coreTypeMappingInfo = new TypeMappingInfo(type, keyOrIndex, unicode, size, rowVersion, precision, scale);
_coreTypeMappingInfo = new TypeMappingInfo(type, elementTypeMapping, keyOrIndex, unicode, size, rowVersion, precision, scale);

IsFixedLength = fixedLength;
StoreTypeName = storeTypeName;
Expand Down Expand Up @@ -341,6 +345,15 @@ public JsonValueReaderWriter? JsonValueReaderWriter
init => _coreTypeMappingInfo = _coreTypeMappingInfo with { JsonValueReaderWriter = value };
}

/// <summary>
/// The element type of the mapping, if any.
/// </summary>
public RelationalTypeMapping? ElementTypeMapping
{
get => (RelationalTypeMapping?)_coreTypeMappingInfo.ElementTypeMapping;
init => _coreTypeMappingInfo = _coreTypeMappingInfo with { ElementTypeMapping = value };
}

/// <summary>
/// Returns a new <see cref="RelationalTypeMappingInfo" /> with the given converter applied.
/// </summary>
Expand Down
54 changes: 28 additions & 26 deletions src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
RelationalStrings.NoneRelationalTypeMappingOnARelationalTypeMappingSource);

private RelationalTypeMapping? FindMappingWithConversion(
in RelationalTypeMappingInfo mappingInfo,
RelationalTypeMappingInfo mappingInfo,
IReadOnlyList<IProperty>? principals)
{
Type? providerClrType = null;
Expand Down Expand Up @@ -114,15 +114,19 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
}
}

var element = principal.GetElementType();
if (element != null)
if (elementMapping == null)
{
elementMapping = FindMapping(element);
var element = principal.GetElementType();
if (element != null)
{
elementMapping = FindMapping(element);
mappingInfo = mappingInfo with { ElementTypeMapping = (RelationalTypeMapping?)elementMapping };
}
}
}
}

var resolvedMapping = FindMappingWithConversion(mappingInfo, providerClrType, customConverter, elementMapping);
var resolvedMapping = FindMappingWithConversion(mappingInfo, providerClrType, customConverter);

ValidateMapping(resolvedMapping, principals?[0]);

Expand All @@ -132,26 +136,23 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
private RelationalTypeMapping? FindMappingWithConversion(
RelationalTypeMappingInfo mappingInfo,
Type? providerClrType,
ValueConverter? customConverter,
CoreTypeMapping? elementMapping)
ValueConverter? customConverter)
=> _explicitMappings.GetOrAdd(
(mappingInfo, providerClrType, customConverter, elementMapping),
(mappingInfo, providerClrType, customConverter, mappingInfo.ElementTypeMapping),
static (k, self) =>
{
var (mappingInfo, providerClrType, customConverter, elementMapping) = k;

var sourceType = mappingInfo.ClrType;
RelationalTypeMapping? mapping = null;
var mapping = providerClrType == null
|| providerClrType == mappingInfo.ClrType
? self.FindMapping(mappingInfo)
: null;

if (elementMapping == null
|| customConverter != null)
if (mapping == null)
{
mapping = providerClrType == null
|| providerClrType == mappingInfo.ClrType
? self.FindMapping(mappingInfo)
: null;

if (mapping == null)
if (elementMapping == null
|| customConverter != null)
{
if (sourceType != null)
{
Expand Down Expand Up @@ -193,10 +194,10 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
mapping ??= self.FindCollectionMapping(mappingInfo, sourceType, providerClrType, elementMapping);
}
}
}
else if (sourceType != null)
{
mapping = self.FindCollectionMapping(mappingInfo, sourceType, providerClrType, elementMapping);
else if (sourceType != null)
{
mapping = self.FindCollectionMapping(mappingInfo, sourceType, providerClrType, elementMapping);
}
}

if (mapping != null
Expand Down Expand Up @@ -312,7 +313,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)

var resolvedMapping = FindMappingWithConversion(
new RelationalTypeMappingInfo(elementType, storeTypeName, storeTypeNameBase, unicode, isFixedLength, size, precision, scale),
providerClrType, customConverter, null);
providerClrType, customConverter);

ValidateMapping(resolvedMapping, null);

Expand Down Expand Up @@ -357,7 +358,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
ValueConverter? customConverter = null;
if (typeConfiguration == null)
{
mappingInfo = new RelationalTypeMappingInfo(type);
mappingInfo = new RelationalTypeMappingInfo(type, (RelationalTypeMapping?)elementMapping);
}
else
{
Expand All @@ -379,6 +380,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
var isFixedLength = (bool?)typeConfiguration[RelationalAnnotationNames.IsFixedLength];
mappingInfo = new RelationalTypeMappingInfo(
customConverter?.ProviderClrType ?? type,
(RelationalTypeMapping?)elementMapping,
storeTypeName,
storeTypeBaseName,
keyOrIndex: false,
Expand All @@ -390,7 +392,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
scale: scale);
}

return FindMappingWithConversion(mappingInfo, providerClrType, customConverter, (RelationalTypeMapping?)elementMapping);
return FindMappingWithConversion(mappingInfo, providerClrType, customConverter);
}

/// <summary>
Expand Down Expand Up @@ -422,7 +424,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
attribute.TypeName, ref unicode, ref size, ref precision, ref scale);

return FindMappingWithConversion(
new RelationalTypeMappingInfo(member, storeTypeName, storeTypeNameBase, unicode, size, precision, scale), null);
new RelationalTypeMappingInfo(member, null, storeTypeName, storeTypeNameBase, unicode, size, precision, scale), null);
}

return FindMappingWithConversion(new RelationalTypeMappingInfo(member), null);
Expand Down Expand Up @@ -496,7 +498,7 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)

return FindMappingWithConversion(
new RelationalTypeMappingInfo(
type, storeTypeName, storeTypeBaseName, keyOrIndex, unicode, size, rowVersion, fixedLength, precision, scale), null);
type, null, storeTypeName, storeTypeBaseName, keyOrIndex, unicode, size, rowVersion, fixedLength, precision, scale), null);
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,20 +349,23 @@ public SqlServerTypeMappingSource(
return Rowversion;
}

var isFixedLength = mappingInfo.IsFixedLength == true;

var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? 900 : null);
if (size is < 0 or > 8000)
if (mappingInfo.ElementTypeMapping == null)
{
size = isFixedLength ? 8000 : null;
}
var isFixedLength = mappingInfo.IsFixedLength == true;

return size == null
? VariableLengthMaxBinary
: new SqlServerByteArrayTypeMapping(
size: size,
fixedLength: isFixedLength,
storeTypePostfix: storeTypeName == null ? StoreTypePostfix.Size : StoreTypePostfix.None);
var size = mappingInfo.Size ?? (mappingInfo.IsKeyOrIndex ? 900 : null);
if (size is < 0 or > 8000)
{
size = isFixedLength ? 8000 : null;
}

return size == null
? VariableLengthMaxBinary
: new SqlServerByteArrayTypeMapping(
size: size,
fixedLength: isFixedLength,
storeTypePostfix: storeTypeName == null ? StoreTypePostfix.Size : StoreTypePostfix.None);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ public static bool IsSpatialiteType(string columnType)
private RelationalTypeMapping? FindRawMapping(RelationalTypeMappingInfo mappingInfo)
{
var clrType = mappingInfo.ClrType;
if (clrType == typeof(byte[]) && mappingInfo.ElementTypeMapping != null)
{
return null;
}

if (clrType != null
&& _clrTypeMappings.TryGetValue(clrType, out var mapping))
{
Expand Down
14 changes: 13 additions & 1 deletion src/EFCore/Storage/TypeMappingInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public TypeMappingInfo(
var mappingHints = customConverter?.MappingHints;
var property = principals[0];

ElementTypeMapping = property.GetElementType()?.FindTypeMapping();
IsKeyOrIndex = property.IsKey() || property.IsForeignKey() || property.IsIndex();
Size = fallbackSize ?? mappingHints?.Size;
IsUnicode = fallbackUnicode ?? mappingHints?.IsUnicode;
Expand All @@ -195,17 +196,19 @@ public TypeMappingInfo(
/// Creates a new instance of <see cref="TypeMappingInfo" />.
/// </summary>
/// <param name="member">The property or field for which mapping is needed.</param>
/// <param name="elementTypeMapping">The type mapping for elements, if known.</param>
/// <param name="unicode">Specifies Unicode or ANSI mapping, or <see langword="null" /> for default.</param>
/// <param name="size">Specifies a size for the mapping, or <see langword="null" /> for default.</param>
/// <param name="precision">Specifies a precision for the mapping, or <see langword="null" /> for default.</param>
/// <param name="scale">Specifies a scale for the mapping, or <see langword="null" /> for default.</param>
public TypeMappingInfo(
MemberInfo member,
CoreTypeMapping? elementTypeMapping = null,
bool? unicode = null,
int? size = null,
int? precision = null,
int? scale = null)
: this(member.GetMemberType())
: this(member.GetMemberType(), elementTypeMapping)
{
IsUnicode = unicode;
Size = size;
Expand All @@ -217,6 +220,7 @@ public TypeMappingInfo(
/// Creates a new instance of <see cref="TypeMappingInfo" />.
/// </summary>
/// <param name="type">The CLR type in the model for which mapping is needed.</param>
/// <param name="elementTypeMapping">The type mapping for elements, if known.</param>
/// <param name="keyOrIndex">If <see langword="true" />, then a special mapping for a key or index may be returned.</param>
/// <param name="unicode">Specifies Unicode or ANSI mapping, or <see langword="null" /> for default.</param>
/// <param name="size">Specifies a size for the mapping, or <see langword="null" /> for default.</param>
Expand All @@ -225,6 +229,7 @@ public TypeMappingInfo(
/// <param name="scale">Specifies a scale for the mapping, or <see langword="null" /> for default.</param>
public TypeMappingInfo(
Type? type = null,
CoreTypeMapping? elementTypeMapping = null,
bool keyOrIndex = false,
bool? unicode = null,
int? size = null,
Expand All @@ -233,6 +238,7 @@ public TypeMappingInfo(
int? scale = null)
{
ClrType = type?.UnwrapNullableType();
ElementTypeMapping = elementTypeMapping;

IsKeyOrIndex = keyOrIndex;
Size = size;
Expand Down Expand Up @@ -272,8 +278,14 @@ public TypeMappingInfo(
ClrType = converter.ProviderClrType.UnwrapNullableType();

JsonValueReaderWriter = source.JsonValueReaderWriter;
ElementTypeMapping = source.ElementTypeMapping;
}

/// <summary>
/// The element type mapping of the mapping, if any.
/// </summary>
public CoreTypeMapping? ElementTypeMapping { get; init; }

/// <summary>
/// Returns a new <see cref="TypeMappingInfo" /> with the given converter applied.
/// </summary>
Expand Down
Loading