Skip to content
Open
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 @@ -281,7 +281,8 @@ private static CosmosTypeMapping Create<
ValueComparer? keyComparer,
CoreTypeMapping? elementMapping,
JsonValueReaderWriter? jsonValueReaderWriter)
=> comparer is null && keyComparer is null && elementMapping is null && jsonValueReaderWriter is null
=> comparer is null && keyComparer is null && elementMapping is null
&& (jsonValueReaderWriter is null || ReferenceEquals(jsonValueReaderWriter, CosmosTypeMapping<T>.Default.JsonValueReaderWriter))
Comment thread
AndriySvyryd marked this conversation as resolved.
? CosmosTypeMapping<T>.Default
: new CosmosTypeMapping<T>(comparer, keyComparer, elementMapping, jsonValueReaderWriter);
Comment thread
Copilot marked this conversation as resolved.

Expand Down
4 changes: 3 additions & 1 deletion src/EFCore.Cosmos/Storage/Internal/CosmosTypeMapping`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public class CosmosTypeMapping<
/// 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>
public static new CosmosTypeMapping<T> Default { get; } = new();
#pragma warning disable EF1001 // Internal EF Core API usage.
public static new CosmosTypeMapping<T> Default { get; } = new(jsonValueReaderWriter: JsonValueReaderWriterSource.FindReaderWriter<T>());
#pragma warning restore EF1001

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore/EFCore.baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -17207,7 +17207,7 @@
]
},
{
"Type": "sealed class Microsoft.EntityFrameworkCore.Storage.Json.JsonSignedEnumReaderWriter<TEnum> : Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter<TEnum> where TEnum : struct, System.Enum",
"Type": "sealed class Microsoft.EntityFrameworkCore.Storage.Json.JsonSignedEnumReaderWriter<TEnum> : Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter<TEnum>",
"Methods": [
{
"Member": "override TEnum FromJsonTyped(ref Microsoft.EntityFrameworkCore.Storage.Json.Utf8JsonReaderManager manager, object? existingObject = null);"
Expand Down Expand Up @@ -17340,7 +17340,7 @@
]
},
{
"Type": "sealed class Microsoft.EntityFrameworkCore.Storage.Json.JsonUnsignedEnumReaderWriter<TEnum> : Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter<TEnum> where TEnum : struct, System.Enum",
"Type": "sealed class Microsoft.EntityFrameworkCore.Storage.Json.JsonUnsignedEnumReaderWriter<TEnum> : Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter<TEnum>",
"Methods": [
{
"Member": "override TEnum FromJsonTyped(ref Microsoft.EntityFrameworkCore.Storage.Json.Utf8JsonReaderManager manager, object? existingObject = null);"
Expand Down
1 change: 0 additions & 1 deletion src/EFCore/Storage/Json/JsonSignedEnumReaderWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace Microsoft.EntityFrameworkCore.Storage.Json;
/// Reads and writes JSON for <see langword="enum" /> values backed by a signed integer.
/// </summary>
public sealed class JsonSignedEnumReaderWriter<TEnum> : JsonValueReaderWriter<TEnum>
where TEnum : struct, Enum

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we had to remove that constraint because the FindReaderWriter<T>, right? If not, it would make sense to me to keep it.

{
private static readonly PropertyInfo InstanceProperty = typeof(JsonSignedEnumReaderWriter<TEnum>).GetProperty(nameof(Instance))!;

Expand Down
1 change: 0 additions & 1 deletion src/EFCore/Storage/Json/JsonUnsignedEnumReaderWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace Microsoft.EntityFrameworkCore.Storage.Json;
/// Reads and writes JSON for <see langword="enum" /> values backed by an unsigned integer.
/// </summary>
public sealed class JsonUnsignedEnumReaderWriter<TEnum> : JsonValueReaderWriter<TEnum>
where TEnum : struct, Enum
{
private static readonly PropertyInfo InstanceProperty = typeof(JsonUnsignedEnumReaderWriter<TEnum>).GetProperty(nameof(Instance))!;

Expand Down
165 changes: 47 additions & 118 deletions src/EFCore/Storage/Json/JsonValueReaderWriterSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,124 +33,53 @@ public JsonValueReaderWriterSource(JsonValueReaderWriterSourceDependencies depen
/// </summary>
protected virtual JsonValueReaderWriterSourceDependencies Dependencies { get; }

/// <inheritdoc />
public virtual JsonValueReaderWriter? FindReaderWriter(Type type)
{
if (type == typeof(int))
{
return JsonInt32ReaderWriter.Instance;
}

if (type == typeof(string))
{
return JsonStringReaderWriter.Instance;
}

if (type == typeof(Guid))
{
return JsonGuidReaderWriter.Instance;
}

if (type == typeof(bool))
{
return JsonBoolReaderWriter.Instance;
}

if (type == typeof(DateTime))
{
return JsonDateTimeReaderWriter.Instance;
}

if (type == typeof(DateTimeOffset))
{
return JsonDateTimeOffsetReaderWriter.Instance;
}

if (type == typeof(decimal))
{
return JsonDecimalReaderWriter.Instance;
}

if (type == typeof(double))
{
return JsonDoubleReaderWriter.Instance;
}

if (type == typeof(long))
{
return JsonInt64ReaderWriter.Instance;
}

if (type == typeof(DateOnly))
{
return JsonDateOnlyReaderWriter.Instance;
}

if (type == typeof(TimeOnly))
{
return JsonTimeOnlyReaderWriter.Instance;
}

if (type == typeof(byte[]))
{
return JsonByteArrayReaderWriter.Instance;
}

if (type == typeof(ulong))
{
return JsonUInt64ReaderWriter.Instance;
}

if (type == typeof(uint))
{
return JsonUInt32ReaderWriter.Instance;
}

if (type == typeof(byte))
{
return JsonByteReaderWriter.Instance;
}

if (type == typeof(char))
{
return JsonCharReaderWriter.Instance;
}

if (type == typeof(float))
{
return JsonFloatReaderWriter.Instance;
}

if (type == typeof(short))
{
return JsonInt16ReaderWriter.Instance;
}

if (type == typeof(sbyte))
{
return JsonSByteReaderWriter.Instance;
}

if (type == typeof(ushort))
{
return JsonUInt16ReaderWriter.Instance;
}

if (type == typeof(TimeSpan))
{
return JsonTimeSpanReaderWriter.Instance;
}
private static readonly MethodInfo FindReaderWriterMethod
= typeof(JsonValueReaderWriterSource).GetMethod(
nameof(FindReaderWriter), genericParameterCount: 1, BindingFlags.Public | BindingFlags.Static, Type.EmptyTypes)!;

if (type.IsEnum)
{
var readerWriterType =
(type.GetEnumUnderlyingType().IsSignedInteger()
? typeof(JsonSignedEnumReaderWriter<>)
: typeof(JsonUnsignedEnumReaderWriter<>))
.MakeGenericType(type);
return (JsonValueReaderWriter?)readerWriterType.GetAnyProperty("Instance")!.GetValue(null);
}
/// <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]
public static JsonValueReaderWriter? FindReaderWriter<T>()
Comment thread
AndriySvyryd marked this conversation as resolved.
=> typeof(T) switch
{
var t when t == typeof(int) => JsonInt32ReaderWriter.Instance,
var t when t == typeof(string) => JsonStringReaderWriter.Instance,
var t when t == typeof(Guid) => JsonGuidReaderWriter.Instance,
var t when t == typeof(bool) => JsonBoolReaderWriter.Instance,
var t when t == typeof(DateTime) => JsonDateTimeReaderWriter.Instance,
var t when t == typeof(DateTimeOffset) => JsonDateTimeOffsetReaderWriter.Instance,
var t when t == typeof(decimal) => JsonDecimalReaderWriter.Instance,
var t when t == typeof(double) => JsonDoubleReaderWriter.Instance,
var t when t == typeof(long) => JsonInt64ReaderWriter.Instance,
var t when t == typeof(DateOnly) => JsonDateOnlyReaderWriter.Instance,
var t when t == typeof(TimeOnly) => JsonTimeOnlyReaderWriter.Instance,
var t when t == typeof(byte[]) => JsonByteArrayReaderWriter.Instance,
var t when t == typeof(ulong) => JsonUInt64ReaderWriter.Instance,
var t when t == typeof(uint) => JsonUInt32ReaderWriter.Instance,
var t when t == typeof(byte) => JsonByteReaderWriter.Instance,
var t when t == typeof(char) => JsonCharReaderWriter.Instance,
var t when t == typeof(float) => JsonFloatReaderWriter.Instance,
var t when t == typeof(short) => JsonInt16ReaderWriter.Instance,
var t when t == typeof(sbyte) => JsonSByteReaderWriter.Instance,
var t when t == typeof(ushort) => JsonUInt16ReaderWriter.Instance,
var t when t == typeof(TimeSpan) => JsonTimeSpanReaderWriter.Instance,
var t when t.IsEnum => typeof(T).GetEnumUnderlyingType().IsSignedInteger()
? JsonSignedEnumReaderWriter<T>.Instance
: JsonUnsignedEnumReaderWriter<T>.Instance,
_ => null
};

return null;
}
/// <inheritdoc />
[RequiresDynamicCode("This method uses reflection to invoke the generic FindReaderWriter<T> method.")]
public virtual JsonValueReaderWriter? FindReaderWriter(Type type)
=> type.ContainsGenericParameters
? null
: (JsonValueReaderWriter?)FindReaderWriterMethod
.MakeGenericMethod(type)
.Invoke(null, null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 0,
relationshipIndex: 0,
storeGenerationIndex: -1);
id.TypeMapping = CosmosTypeMapping<int>.Default.Clone(
jsonValueReaderWriter: JsonInt32ReaderWriter.Instance);
id.TypeMapping = CosmosTypeMapping<int>.Default;
id.SetCurrentValueComparer(new EntryCurrentValueComparer<int>(id));

var partitionId = runtimeEntityType.AddProperty(
Expand Down Expand Up @@ -216,8 +215,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 5,
relationshipIndex: -1,
storeGenerationIndex: -1);
__id.TypeMapping = CosmosTypeMapping<string>.Default.Clone(
jsonValueReaderWriter: JsonStringReaderWriter.Instance);
__id.TypeMapping = CosmosTypeMapping<string>.Default;
__id.AddAnnotation("Cosmos:PropertyName", "id");

var __jObject = runtimeEntityType.AddProperty(
Expand Down Expand Up @@ -260,8 +258,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 7,
relationshipIndex: -1,
storeGenerationIndex: 1);
_etag.TypeMapping = CosmosTypeMapping<string>.Default.Clone(
jsonValueReaderWriter: JsonStringReaderWriter.Instance);
_etag.TypeMapping = CosmosTypeMapping<string>.Default;

var key = runtimeEntityType.AddKey(
new[] { id, partitionId });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 0,
relationshipIndex: 0,
storeGenerationIndex: 0);
principalId.TypeMapping = CosmosTypeMapping<long>.Default.Clone(
jsonValueReaderWriter: JsonInt64ReaderWriter.Instance);
principalId.TypeMapping = CosmosTypeMapping<long>.Default;
principalId.SetCurrentValueComparer(new EntryCurrentValueComparer<long>(principalId));

var principalAlternateId = runtimeEntityType.AddProperty(
Expand Down Expand Up @@ -141,8 +140,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: -1,
relationshipIndex: -1,
storeGenerationIndex: -1);
id.TypeMapping = CosmosTypeMapping<byte>.Default.Clone(
jsonValueReaderWriter: JsonByteReaderWriter.Instance);
id.TypeMapping = CosmosTypeMapping<byte>.Default;
id.SetComparer(new NullableValueComparer<byte>(id.TypeMapping.Comparer));

var __id = runtimeEntityType.AddProperty(
Expand All @@ -161,8 +159,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 3,
relationshipIndex: -1,
storeGenerationIndex: -1);
__id.TypeMapping = CosmosTypeMapping<string>.Default.Clone(
jsonValueReaderWriter: JsonStringReaderWriter.Instance);
__id.TypeMapping = CosmosTypeMapping<string>.Default;
__id.AddAnnotation("Cosmos:PropertyName", "id");

var __jObject = runtimeEntityType.AddProperty(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Storage.Json;
using Newtonsoft.Json.Linq;

#pragma warning disable 219, 612, 618
Expand Down Expand Up @@ -65,8 +64,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: -1,
relationshipIndex: -1,
storeGenerationIndex: -1);
data.TypeMapping = CosmosTypeMapping<string>.Default.Clone(
jsonValueReaderWriter: JsonStringReaderWriter.Instance);
data.TypeMapping = CosmosTypeMapping<string>.Default;

var money = runtimeEntityType.AddProperty(
"Money",
Expand All @@ -85,8 +83,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas
shadowIndex: 5,
relationshipIndex: -1,
storeGenerationIndex: -1);
money.TypeMapping = CosmosTypeMapping<decimal>.Default.Clone(
jsonValueReaderWriter: JsonDecimalReaderWriter.Instance);
money.TypeMapping = CosmosTypeMapping<decimal>.Default;

return runtimeEntityType;
}
Expand Down
Loading
Loading