diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
index d06a982a176..d2d8f723f72 100644
--- a/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
+++ b/src/EFCore.Design/Scaffolding/Internal/CSharpRuntimeModelCodeGenerator.cs
@@ -1254,9 +1254,10 @@ private void Create(
var keyValueComparer = property.GetKeyValueComparer();
var typeMappingKeyComparer = property.GetTypeMapping().KeyComparer;
- if (valueComparer != keyValueComparer
- && (!parameters.ForNativeAot || keyValueComparer != typeMappingKeyComparer)
- && (parameters.ForNativeAot || property[CoreAnnotationNames.ValueComparer] != null))
+ if ((valueComparer != keyValueComparer
+ && (!parameters.ForNativeAot || keyValueComparer != typeMappingKeyComparer)
+ && (parameters.ForNativeAot || property[CoreAnnotationNames.ValueComparer] != null))
+ )
{
SetValueComparer(keyValueComparer, typeMappingKeyComparer, nameof(CoreTypeMapping.KeyComparer), propertyParameters);
}
diff --git a/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs
index 7b888e559ec..9caf24ac49c 100644
--- a/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs
+++ b/src/EFCore.Relational/Design/Internal/RelationalCSharpRuntimeAnnotationCodeGenerator.cs
@@ -2483,8 +2483,42 @@ public override bool Create(
return false;
}
- var defaultInstance = (RelationalTypeMapping?)CreateDefaultTypeMapping(relationalTypeMapping, parameters);
- if (defaultInstance == null)
+ var defaultInstance = (RelationalTypeMapping)CreateDefaultTypeMapping(relationalTypeMapping, parameters);
+ var comparer = valueComparer ?? relationalTypeMapping.Comparer;
+ var keyComparer = keyValueComparer ?? relationalTypeMapping.KeyComparer;
+ var providerComparer = providerValueComparer ?? relationalTypeMapping.ProviderValueComparer;
+ var storeTypeDifferent = relationalTypeMapping.StoreType != defaultInstance.StoreType;
+ var sizeDifferent = relationalTypeMapping.Size != null
+ && relationalTypeMapping.Size != defaultInstance.Size;
+ var precisionDifferent = relationalTypeMapping.Precision != null
+ && relationalTypeMapping.Precision != defaultInstance.Precision;
+ var scaleDifferent = relationalTypeMapping.Scale != null
+ && relationalTypeMapping.Scale != defaultInstance.Scale;
+ var dbTypeDifferent = relationalTypeMapping.DbType != null
+ && relationalTypeMapping.DbType != defaultInstance.DbType;
+ var isUnicodeDifferent = relationalTypeMapping.IsUnicode != defaultInstance.IsUnicode;
+ var isFixedLengthDifferent = relationalTypeMapping.IsFixedLength != defaultInstance.IsFixedLength;
+ var typeDifferent = relationalTypeMapping.Converter == null
+ && relationalTypeMapping.ClrType != defaultInstance.ClrType;
+ var storeTypePostfixDifferent = relationalTypeMapping.StoreTypePostfix != defaultInstance.StoreTypePostfix;
+ if (valueComparer == null
+ && keyValueComparer == null
+ && providerValueComparer == null
+ && comparer == defaultInstance.Comparer
+ && keyComparer == defaultInstance.KeyComparer
+ && providerComparer == defaultInstance.ProviderValueComparer
+ && !storeTypeDifferent
+ && !sizeDifferent
+ && !precisionDifferent
+ && !scaleDifferent
+ && !dbTypeDifferent
+ && !isUnicodeDifferent
+ && !isFixedLengthDifferent
+ && relationalTypeMapping.Converter == defaultInstance.Converter
+ && !typeDifferent
+ && !storeTypePostfixDifferent
+ && relationalTypeMapping.JsonValueReaderWriter == defaultInstance.JsonValueReaderWriter
+ && relationalTypeMapping.ElementTypeMapping == defaultInstance.ElementTypeMapping)
{
return true;
}
@@ -2495,27 +2529,15 @@ public override bool Create(
mainBuilder
.Append("comparer: ");
- Create(valueComparer ?? relationalTypeMapping.Comparer, parameters, code);
+ Create(comparer, parameters, code);
mainBuilder.AppendLine(",")
.Append("keyComparer: ");
- Create(keyValueComparer ?? relationalTypeMapping.KeyComparer, parameters, code);
+ Create(keyComparer, parameters, code);
mainBuilder.AppendLine(",")
.Append("providerValueComparer: ");
- Create(providerValueComparer ?? relationalTypeMapping.ProviderValueComparer, parameters, code);
-
- var storeTypeDifferent = relationalTypeMapping.StoreType != defaultInstance.StoreType;
- var sizeDifferent = relationalTypeMapping.Size != null
- && relationalTypeMapping.Size != defaultInstance.Size;
- var precisionDifferent = relationalTypeMapping.Precision != null
- && relationalTypeMapping.Precision != defaultInstance.Precision;
- var scaleDifferent = relationalTypeMapping.Scale != null
- && relationalTypeMapping.Scale != defaultInstance.Scale;
- var dbTypeDifferent = relationalTypeMapping.DbType != null
- && relationalTypeMapping.DbType != defaultInstance.DbType;
- var isUnicodeDifferent = relationalTypeMapping.IsUnicode != defaultInstance.IsUnicode;
- var isFixedLengthDifferent = relationalTypeMapping.IsFixedLength != defaultInstance.IsFixedLength;
+ Create(providerComparer, parameters, code);
if (storeTypeDifferent
|| sizeDifferent
|| precisionDifferent
@@ -2586,15 +2608,12 @@ public override bool Create(
Create(relationalTypeMapping.Converter, parameters, code);
}
- var typeDifferent = relationalTypeMapping.Converter == null
- && relationalTypeMapping.ClrType != defaultInstance.ClrType;
if (typeDifferent)
{
mainBuilder.AppendLine(",")
.Append($"clrType: {code.Literal(relationalTypeMapping.ClrType)}");
}
- var storeTypePostfixDifferent = relationalTypeMapping.StoreTypePostfix != defaultInstance.StoreTypePostfix;
if (storeTypePostfixDifferent)
{
mainBuilder.AppendLine(",")
diff --git a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs
index 65daf72ad25..8172bb96bed 100644
--- a/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs
+++ b/src/EFCore/Design/Internal/CSharpRuntimeAnnotationCodeGenerator.cs
@@ -586,6 +586,27 @@ public static void CreateJsonValueReaderWriter(
}
}
+ ///
+ public virtual bool Create(
+ CoreTypeMapping typeMapping,
+ IProperty property,
+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
+ {
+ var keyValueComparer = property.GetKeyValueComparer();
+ var typeMappingKeyComparer = property.GetTypeMapping().KeyComparer;
+ keyValueComparer = parameters.ForNativeAot
+ && (property.IsKey()
+ || property.IsForeignKey()
+ || property.IsUniqueIndex())
+ && keyValueComparer == typeMappingKeyComparer
+ && keyValueComparer.IsDefault()
+ && keyValueComparer.Type == property.ClrType
+ ? keyValueComparer
+ : null;
+
+ return Create(typeMapping, parameters, keyValueComparer: keyValueComparer);
+ }
+
///
public virtual bool Create(
CoreTypeMapping typeMapping,
@@ -597,7 +618,21 @@ public virtual bool Create(
var mainBuilder = parameters.MainBuilder;
var code = Dependencies.CSharpHelper;
var defaultInstance = CreateDefaultTypeMapping(typeMapping, parameters);
- if (defaultInstance == null)
+ var comparer = valueComparer ?? typeMapping.Comparer;
+ var keyComparer = keyValueComparer ?? typeMapping.KeyComparer;
+ var providerComparer = providerValueComparer ?? typeMapping.ProviderValueComparer;
+ var typeDifferent = typeMapping.Converter == null
+ && typeMapping.ClrType != defaultInstance.ClrType;
+ if (valueComparer == null
+ && keyValueComparer == null
+ && providerValueComparer == null
+ && comparer == defaultInstance.Comparer
+ && keyComparer == defaultInstance.KeyComparer
+ && providerComparer == defaultInstance.ProviderValueComparer
+ && typeMapping.Converter == defaultInstance.Converter
+ && !typeDifferent
+ && typeMapping.JsonValueReaderWriter == defaultInstance.JsonValueReaderWriter
+ && typeMapping.ElementTypeMapping == defaultInstance.ElementTypeMapping)
{
return true;
}
@@ -608,15 +643,15 @@ public virtual bool Create(
mainBuilder
.Append("comparer: ");
- Create(valueComparer ?? typeMapping.Comparer, parameters, code);
+ Create(comparer, parameters, code);
mainBuilder.AppendLine(",")
.Append("keyComparer: ");
- Create(keyValueComparer ?? typeMapping.KeyComparer, parameters, code);
+ Create(keyComparer, parameters, code);
mainBuilder.AppendLine(",")
.Append("providerValueComparer: ");
- Create(providerValueComparer ?? typeMapping.ProviderValueComparer, parameters, code);
+ Create(providerComparer, parameters, code);
if (typeMapping.Converter != null
&& typeMapping.Converter != defaultInstance.Converter)
@@ -627,8 +662,6 @@ public virtual bool Create(
Create(typeMapping.Converter, parameters, code);
}
- var typeDifferent = typeMapping.Converter == null
- && typeMapping.ClrType != defaultInstance.ClrType;
if (typeDifferent)
{
mainBuilder.AppendLine(",")
@@ -666,7 +699,7 @@ public virtual bool Create(
/// 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.
///
- protected virtual CoreTypeMapping? CreateDefaultTypeMapping(
+ protected virtual CoreTypeMapping CreateDefaultTypeMapping(
CoreTypeMapping typeMapping,
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
@@ -689,7 +722,6 @@ public virtual bool Create(
.Append(code.Reference(typeMappingType))
.Append(".Default");
- var defaultInstance = (CoreTypeMapping)defaultProperty.GetValue(null)!;
- return typeMapping == defaultInstance ? null : defaultInstance;
+ return (CoreTypeMapping)defaultProperty.GetValue(null)!;
}
}
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextAssemblyAttributes.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextAssemblyAttributes.cs
new file mode 100644
index 00000000000..c32d233bbdb
--- /dev/null
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextAssemblyAttributes.cs
@@ -0,0 +1,9 @@
+//
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using TestNamespace;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+[assembly: DbContextModel(typeof(DbContext), typeof(DbContextModel), ProviderName = "Microsoft.EntityFrameworkCore.InMemory")]
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModel.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModel.cs
new file mode 100644
index 00000000000..e5896994b93
--- /dev/null
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModel.cs
@@ -0,0 +1,47 @@
+//
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace TestNamespace;
+
+[DbContext(typeof(DbContext))]
+public partial class DbContextModel : RuntimeModel
+{
+ private static readonly bool _useOldBehavior31751 =
+ System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751;
+
+ static DbContextModel()
+ {
+ var model = new DbContextModel();
+
+ if (_useOldBehavior31751)
+ {
+ model.Initialize();
+ }
+ else
+ {
+ var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024);
+ thread.Start();
+ thread.Join();
+
+ void RunInitialization()
+ {
+ model.Initialize();
+ }
+ }
+
+ model.Customize();
+ _instance = (DbContextModel)model.FinalizeModel();
+ }
+
+ private static DbContextModel _instance;
+ public static IModel Instance => _instance;
+
+ partial void Initialize();
+
+ partial void Customize();
+}
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModelBuilder.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModelBuilder.cs
new file mode 100644
index 00000000000..bddee0d2e7d
--- /dev/null
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/DbContextModelBuilder.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace TestNamespace;
+
+public partial class DbContextModel
+{
+ private DbContextModel()
+ : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 1)
+ {
+ }
+
+ partial void Initialize()
+ {
+ var index = IndexEntityType.Create(this);
+
+ IndexEntityType.CreateAnnotations(index);
+
+ }
+}
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexEntityType.cs
new file mode 100644
index 00000000000..b04289b7f44
--- /dev/null
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexEntityType.cs
@@ -0,0 +1,129 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
+using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
+using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Scaffolding;
+using Microsoft.EntityFrameworkCore.Storage.Json;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace TestNamespace;
+
+[EntityFrameworkInternal]
+public partial class IndexEntityType
+{
+ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null)
+ {
+ var runtimeEntityType = model.AddEntityType(
+ "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelInMemoryTest+Index",
+ typeof(CompiledModelInMemoryTest.Index),
+ baseEntityType,
+ propertyCount: 1,
+ keyCount: 1);
+
+ var id = runtimeEntityType.AddProperty(
+ "Id",
+ typeof(Guid),
+ propertyInfo: typeof(CompiledModelInMemoryTest.Index).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ fieldInfo: typeof(CompiledModelInMemoryTest.Index).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
+ valueGenerated: ValueGenerated.OnAdd,
+ afterSaveBehavior: PropertySaveBehavior.Throw,
+ sentinel: new Guid("00000000-0000-0000-0000-000000000000"));
+ id.SetGetter(
+ Guid (CompiledModelInMemoryTest.Index instance) => IndexUnsafeAccessors.Id(instance),
+ bool (CompiledModelInMemoryTest.Index instance) => IndexUnsafeAccessors.Id(instance) == new Guid("00000000-0000-0000-0000-000000000000"));
+ id.SetSetter(
+ CompiledModelInMemoryTest.Index (CompiledModelInMemoryTest.Index instance, Guid value) =>
+ {
+ IndexUnsafeAccessors.Id(instance) = value;
+ return instance;
+ });
+ id.SetMaterializationSetter(
+ CompiledModelInMemoryTest.Index (CompiledModelInMemoryTest.Index instance, Guid value) =>
+ {
+ IndexUnsafeAccessors.Id(instance) = value;
+ return instance;
+ });
+ id.SetAccessors(
+ Guid (IInternalEntry entry) => (entry.FlaggedAsStoreGenerated(0) ? entry.ReadStoreGeneratedValue(0) : (entry.FlaggedAsTemporary(0) && IndexUnsafeAccessors.Id(((CompiledModelInMemoryTest.Index)(entry.Entity))) == new Guid("00000000-0000-0000-0000-000000000000") ? entry.ReadTemporaryValue(0) : IndexUnsafeAccessors.Id(((CompiledModelInMemoryTest.Index)(entry.Entity))))),
+ Guid (IInternalEntry entry) => IndexUnsafeAccessors.Id(((CompiledModelInMemoryTest.Index)(entry.Entity))),
+ Guid (IInternalEntry entry) => entry.ReadOriginalValue(id, 0),
+ Guid (IInternalEntry entry) => ((InternalEntityEntry)entry).ReadRelationshipSnapshotValue(id, 0));
+ id.SetPropertyIndexes(
+ index: 0,
+ originalValueIndex: 0,
+ shadowIndex: -1,
+ relationshipIndex: 0,
+ storeGenerationIndex: 0);
+ id.TypeMapping = InMemoryTypeMapping.Default.Clone(
+ comparer: new ValueComparer(
+ bool (Guid v1, Guid v2) => v1 == v2,
+ int (Guid v) => ((object)v).GetHashCode(),
+ Guid (Guid v) => v),
+ keyComparer: new ValueComparer(
+ bool (Guid v1, Guid v2) => v1 == v2,
+ int (Guid v) => ((object)v).GetHashCode(),
+ Guid (Guid v) => v),
+ providerValueComparer: new ValueComparer(
+ bool (Guid v1, Guid v2) => v1 == v2,
+ int (Guid v) => ((object)v).GetHashCode(),
+ Guid (Guid v) => v),
+ clrType: typeof(Guid),
+ jsonValueReaderWriter: JsonGuidReaderWriter.Instance);
+ id.SetCurrentValueComparer(new EntryCurrentValueComparer(id));
+
+ var key = runtimeEntityType.AddKey(
+ new[] { id });
+ runtimeEntityType.SetPrimaryKey(key);
+
+ return runtimeEntityType;
+ }
+
+ public static void CreateAnnotations(RuntimeEntityType runtimeEntityType)
+ {
+ var id = runtimeEntityType.FindProperty("Id");
+ var key = runtimeEntityType.FindKey(new[] { id });
+ key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key));
+ key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key));
+ runtimeEntityType.SetOriginalValuesFactory(
+ ISnapshot (IInternalEntry source) =>
+ {
+ var structuralType = ((CompiledModelInMemoryTest.Index)(source.Entity));
+ return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)))));
+ });
+ runtimeEntityType.SetStoreGeneratedValuesFactory(
+ ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(default(Guid))))));
+ runtimeEntityType.SetTemporaryValuesFactory(
+ ISnapshot (IInternalEntry source) => ((ISnapshot)(new Snapshot(default(Guid)))));
+ runtimeEntityType.SetShadowValuesFactory(
+ ISnapshot (IDictionary source) => Snapshot.Empty);
+ runtimeEntityType.SetEmptyShadowValuesFactory(
+ ISnapshot () => Snapshot.Empty);
+ runtimeEntityType.SetRelationshipSnapshotFactory(
+ ISnapshot (IInternalEntry source) =>
+ {
+ var structuralType = ((CompiledModelInMemoryTest.Index)(source.Entity));
+ return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id)))));
+ });
+ runtimeEntityType.SetCounts(new PropertyCounts(
+ propertyCount: 1,
+ navigationCount: 0,
+ complexPropertyCount: 0,
+ complexCollectionCount: 0,
+ originalValueCount: 1,
+ shadowCount: 0,
+ relationshipCount: 1,
+ storeGeneratedCount: 1));
+
+ Customize(runtimeEntityType);
+ }
+
+ static partial void Customize(RuntimeEntityType runtimeEntityType);
+}
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexUnsafeAccessors.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexUnsafeAccessors.cs
new file mode 100644
index 00000000000..0b6a51075fe
--- /dev/null
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/NativeAOT_default_key_comparer_is_emitted/IndexUnsafeAccessors.cs
@@ -0,0 +1,15 @@
+//
+using System;
+using System.Runtime.CompilerServices;
+using Microsoft.EntityFrameworkCore.Scaffolding;
+
+#pragma warning disable 219, 612, 618
+#nullable disable
+
+namespace TestNamespace;
+
+public static class IndexUnsafeAccessors
+{
+ [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")]
+ public static extern ref Guid Id(CompiledModelInMemoryTest.Index @this);
+}
diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs
index 254cecb2d74..1547bdb056c 100644
--- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs
+++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/CompiledModelInMemoryTest.cs
@@ -60,6 +60,21 @@ public virtual Task Self_referential_property()
}
);
+ [Fact]
+ public virtual Task NativeAOT_default_key_comparer_is_emitted()
+ => Test(
+ modelBuilder => modelBuilder.Entity(),
+ model =>
+ {
+ var id = model.FindEntityType(typeof(Index))!.FindProperty(nameof(Index.Id))!;
+ var comparer = Assert.IsAssignableFrom>(id.GetKeyValueComparer());
+ var value = Guid.NewGuid();
+
+ Assert.True(comparer.Equals(value, value));
+ Assert.False(comparer.Equals(value, Guid.NewGuid()));
+ },
+ options: new CompiledModelCodeGenerationOptions { UseNullableReferenceTypes = true, ForNativeAot = true });
+
public class SelfReferentialEntity
where T : struct
{