diff --git a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs index e3a33708622..2f96e92966e 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Linq; using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; // ReSharper disable once CheckNamespace @@ -15,7 +17,8 @@ namespace Microsoft.EntityFrameworkCore; /// public static class CosmosPropertyExtensions { - /// + private static readonly bool _useOldBehavior31664 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31664", out var enabled31664) && enabled31664;/// /// Returns the property name that the property is mapped to when targeting Cosmos. /// /// The property. @@ -35,7 +38,8 @@ private static string GetDefaultJsonPropertyName(IReadOnlyProperty property) var pk = property.FindContainingPrimaryKey(); if (pk != null && (property.ClrType == typeof(int) || ownership.Properties.Contains(property)) - && pk.Properties.Count == ownership.Properties.Count + (ownership.IsUnique ? 0 : 1) + && (property.IsShadowProperty() || _useOldBehavior31664) + && pk.Properties.Count == ownership.Properties.Count + (ownership.IsUnique ? 0 : 1) && ownership.Properties.All(fkProperty => pk.Properties.Contains(fkProperty))) { return ""; diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosValueGenerationConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosValueGenerationConvention.cs index 50ddd2f2a2b..628b41a8d30 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosValueGenerationConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosValueGenerationConvention.cs @@ -17,7 +17,8 @@ public class CosmosValueGenerationConvention : ValueGenerationConvention, IEntityTypeAnnotationChangedConvention { - /// + private static readonly bool _useOldBehavior31664 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31664", out var enabled31664) && enabled31664;/// /// Creates a new instance of . /// /// Parameter object containing dependencies for this convention. @@ -80,6 +81,7 @@ public virtual void ProcessEntityTypeAnnotationChanged( if (pk != null && !property.IsForeignKey() && pk.Properties.Count == ownership.Properties.Count + 1 + && (property.IsShadowProperty() || _useOldBehavior31664) && ownership.Properties.All(fkProperty => pk.Properties.Contains(fkProperty))) { return ValueGenerated.OnAddOrUpdate; diff --git a/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs index 9faad7252fb..46da3a12f7c 100644 --- a/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs +++ b/src/EFCore.Cosmos/Metadata/Internal/CosmosPropertyExtensions.cs @@ -21,12 +21,12 @@ public static bool IsOrdinalKeyProperty(this IReadOnlyProperty property) { Check.DebugAssert( property.DeclaringEntityType.IsOwned(), $"Expected {property.DeclaringEntityType.DisplayName()} to be owned."); - Check.DebugAssert(property.GetJsonPropertyName().Length == 0, $"Expected {property.Name} to be non-persisted."); return property.FindContainingPrimaryKey() is IReadOnlyKey key && key.Properties.Count > 1 && !property.IsForeignKey() && property.ClrType == typeof(int) - && (property.ValueGenerated & ValueGenerated.OnAdd) != 0; + && (property.ValueGenerated & ValueGenerated.OnAdd) != 0 + && property.GetJsonPropertyName().Length == 0; } } diff --git a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs index 56cfd4917bd..a3fe318d41e 100644 --- a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs @@ -35,7 +35,7 @@ public ArrayPropertyValues(InternalEntityEntry internalEntry, object?[] values) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public override object ToObject() - => MaterializerSource.GetMaterializer(EntityType)( + => EntityType.GetOrCreateMaterializer(MaterializerSource)( new MaterializationContext( new ValueBuffer(_values), InternalEntry.Context)); diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs index d8b9928f258..b436eb171d9 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs @@ -291,7 +291,7 @@ public virtual InternalEntityEntry CreateEntry(IDictionary valu } var valueBuffer = new ValueBuffer(valuesArray); - var entity = EntityMaterializerSource.GetMaterializer(entityType)(new MaterializationContext(valueBuffer, Context)); + var entity = entityType.GetOrCreateMaterializer(EntityMaterializerSource)(new MaterializationContext(valueBuffer, Context)); var shadowPropertyValueBuffer = new ValueBuffer(shadowPropertyValuesArray); var entry = new InternalEntityEntry(this, entityType, entity, shadowPropertyValueBuffer); diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs index 52df30d463c..583d1af8b07 100644 --- a/src/EFCore/Infrastructure/ModelValidator.cs +++ b/src/EFCore/Infrastructure/ModelValidator.cs @@ -574,14 +574,15 @@ protected virtual void ValidateInheritanceMapping( protected virtual void ValidateDiscriminatorValues(IEntityType rootEntityType) { var derivedTypes = rootEntityType.GetDerivedTypesInclusive().ToList(); - if (derivedTypes.Count == 1) - { - return; - } + var discriminatorProperty = rootEntityType.FindDiscriminatorProperty(); - if (discriminatorProperty == null) - { + if (discriminatorProperty == null){ + if (derivedTypes.Count == 1) + { + return; + } + throw new InvalidOperationException( CoreStrings.NoDiscriminatorProperty(rootEntityType.DisplayName())); } diff --git a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs index 58f10d4a7a3..9c85bfe6225 100644 --- a/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs +++ b/src/EFCore/Metadata/Conventions/RuntimeModelConvention.cs @@ -44,7 +44,7 @@ public virtual IModel ProcessModelFinalized(IModel model) protected virtual RuntimeModel Create(IModel model) { var runtimeModel = new RuntimeModel(); - runtimeModel.SetSkipDetectChanges(((IRuntimeModel)model).SkipDetectChanges); + runtimeModel.ModelId = model.ModelId;runtimeModel.SetSkipDetectChanges(((IRuntimeModel)model).SkipDetectChanges); ((IModel)runtimeModel).ModelDependencies = model.ModelDependencies!; var entityTypes = model.GetEntityTypesInHierarchicalOrder(); diff --git a/src/EFCore/Metadata/IReadOnlyEntityType.cs b/src/EFCore/Metadata/IReadOnlyEntityType.cs index b9fe2c3cd06..ed3b045326f 100644 --- a/src/EFCore/Metadata/IReadOnlyEntityType.cs +++ b/src/EFCore/Metadata/IReadOnlyEntityType.cs @@ -3,6 +3,9 @@ using System.Text; using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Utilities; namespace Microsoft.EntityFrameworkCore.Metadata; @@ -778,6 +781,31 @@ string ToDebugString(MetadataDebugStringOptions options = MetadataDebugStringOpt { var builder = new StringBuilder(); var indentString = new string(' ', indent); + /// + /// 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. + /// + [EntityFrameworkInternal] + Func GetOrCreateMaterializer(IEntityMaterializerSource source); + + /// + /// + /// Creates a human-readable representation of the given metadata. + /// + /// + /// Warning: Do not rely on the format of the returned string. + /// It is designed for debugging only and may change arbitrarily between releases. + /// + /// + /// Options for generating the string. + /// The number of indent spaces to use before each new line. + /// A human-readable representation. + string ToDebugString(MetadataDebugStringOptions options = MetadataDebugStringOptions.ShortDefault, int indent = 0) + { + var builder = new StringBuilder(); + var indentString = new string(' ', indent); try { diff --git a/src/EFCore/Metadata/IReadOnlyModel.cs b/src/EFCore/Metadata/IReadOnlyModel.cs index 2621039a6f2..965dbeed542 100644 --- a/src/EFCore/Metadata/IReadOnlyModel.cs +++ b/src/EFCore/Metadata/IReadOnlyModel.cs @@ -196,6 +196,15 @@ private static int GetDerivedLevel(Type? derivedType, Dictionary deri } /// + /// 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. + /// + [EntityFrameworkInternal] + public Guid ModelId { get; } + + /// /// /// Creates a human-readable representation of the given metadata. /// diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs index 213e1088828..36aefbbe701 100644 --- a/src/EFCore/Metadata/Internal/EntityType.cs +++ b/src/EFCore/Metadata/Internal/EntityType.cs @@ -5,6 +5,11 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.EntityFrameworkCore.Utilities; namespace Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -3574,7 +3579,17 @@ private void UpdateServiceOnlyConstructorBindingConfigurationSource(Configuratio => _serviceOnlyConstructorBindingConfigurationSource = configurationSource.Max(_serviceOnlyConstructorBindingConfigurationSource); - #endregion + /// + /// 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. + /// + [EntityFrameworkInternal] + public virtual Func GetOrCreateMaterializer(IEntityMaterializerSource source) + => source.GetMaterializer(this); + + #endregion #region Explicit interface implementations diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs index e05b93e0236..a02c191a012 100644 --- a/src/EFCore/Metadata/Internal/Model.cs +++ b/src/EFCore/Metadata/Internal/Model.cs @@ -454,6 +454,14 @@ public virtual IEnumerable FindEntityTypes(Type type) } /// + /// 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. + /// + public virtual Guid ModelId { get; } = Guid.NewGuid(); + + /// /// 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 diff --git a/src/EFCore/Metadata/RuntimeEntityType.cs b/src/EFCore/Metadata/RuntimeEntityType.cs index 69a18b52228..82eb446b5f2 100644 --- a/src/EFCore/Metadata/RuntimeEntityType.cs +++ b/src/EFCore/Metadata/RuntimeEntityType.cs @@ -5,6 +5,11 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Query.Internal; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.EntityFrameworkCore.ValueGeneration; namespace Microsoft.EntityFrameworkCore.Metadata; @@ -65,6 +70,7 @@ private readonly SortedDictionary _triggers private Func? _emptyShadowValuesFactory; private IProperty[]? _foreignKeyProperties; private IProperty[]? _valueGeneratingProperties; + private Func? _materializer; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -844,6 +850,20 @@ public virtual InstantiationBinding? ServiceOnlyConstructorBinding => type.FindIndexerProperty(); /// + /// 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. + /// + [EntityFrameworkInternal] + public virtual Func GetOrCreateMaterializer(IEntityMaterializerSource source) + => EntityMaterializerSource.UseOldBehavior31866 + ? source.GetMaterializer(this) + : NonCapturingLazyInitializer.EnsureInitialized( + ref _materializer, this, source, + static (e, s) => s.GetMaterializer(e)); + + /// /// Returns a string that represents the current object. /// /// A string that represents the current object. diff --git a/src/EFCore/Metadata/RuntimeModel.cs b/src/EFCore/Metadata/RuntimeModel.cs index 9ca509cecb1..37bf70166f2 100644 --- a/src/EFCore/Metadata/RuntimeModel.cs +++ b/src/EFCore/Metadata/RuntimeModel.cs @@ -136,6 +136,15 @@ private IEnumerable FindEntityTypes(Type type) } /// + /// 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. + /// + [EntityFrameworkInternal] + public virtual Guid ModelId { get; set; } + + /// /// Adds configuration for a scalar type. /// /// The type of value the property will hold. @@ -302,4 +311,14 @@ IEnumerable IModel.GetTypeMappingConfigurations() => _typeConfigurations.Count == 0 ? null : _typeConfigurations.GetValueOrDefault(propertyType); + /// + ITypeMappingConfiguration? IModel.FindTypeMappingConfiguration(Type propertyType) + => _typeConfigurations.Count == 0 + ? null + : _typeConfigurations.GetValueOrDefault(propertyType); + + /// + Guid IReadOnlyModel.ModelId + => ModelId; + } } diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs index de9d3009197..b5a13c62243 100644 --- a/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/EFCore/Properties/CoreStrings.Designer.cs @@ -1734,7 +1734,7 @@ public static string NoDiscriminatorProperty(object? entityType) entityType); /// - /// The entity type '{entityType}' is part of a hierarchy, but does not have a discriminator value configured. + /// The entity type '{entityType}' has a discriminator property, but does not have a discriminator value configured. /// public static string NoDiscriminatorValue(object? entityType) => string.Format( diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx index 32a8f8bbfab..9c02ee5268b 100644 --- a/src/EFCore/Properties/CoreStrings.resx +++ b/src/EFCore/Properties/CoreStrings.resx @@ -1065,7 +1065,7 @@ The entity type '{entityType}' is part of a hierarchy, but does not have a discriminator property configured. - The entity type '{entityType}' is part of a hierarchy, but does not have a discriminator value configured. + The entity type '{entityType}' has a discriminator property, but does not have a discriminator value configured. Entity Framework services have not been added to the internal service provider. Either remove the call to 'UseInternalServiceProvider' so that Entity Framework will manage its own internal services, or use the method from your database provider to add the required services to the service provider (e.g. 'AddEntityFrameworkSqlServer'). diff --git a/src/EFCore/Query/Internal/EntityMaterializerSource.cs b/src/EFCore/Query/Internal/EntityMaterializerSource.cs index 7ba6aea906d..01e66cfce7f 100644 --- a/src/EFCore/Query/Internal/EntityMaterializerSource.cs +++ b/src/EFCore/Query/Internal/EntityMaterializerSource.cs @@ -14,7 +14,14 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal; /// public class EntityMaterializerSource : IEntityMaterializerSource { - private ConcurrentDictionary>? _materializers; + /// + /// 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. + /// + public static readonly bool UseOldBehavior31866 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31866", out var enabled31866) && enabled31866;private ConcurrentDictionary>? _materializers; private ConcurrentDictionary>? _emptyMaterializers; private readonly List _bindingInterceptors; private readonly IMaterializationInterceptor? _materializationInterceptor; @@ -355,21 +362,29 @@ private ConcurrentDictionary> ref _materializers, () => new ConcurrentDictionary>()); - /// - /// 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. - /// - public virtual Func GetMaterializer( - IEntityType entityType) - => Materializers.GetOrAdd( - entityType, - static (e, self) => + /// + /// 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. + /// + public virtual Func GetMaterializer(IEntityType entityType) + { + return UseOldBehavior31866 + ? Materializers.GetOrAdd(entityType, static (e, s) => CreateMaterializer(s, e), this) + : CreateMaterializer(this, entityType); + + static Func CreateMaterializer(EntityMaterializerSource self, IEntityType e) { var materializationContextParameter = Expression.Parameter(typeof(MaterializationContext), "materializationContext"); + return Expression.Lambda>( + self.CreateMaterializeExpression(e, "instance", materializationContextParameter), + materializationContextParameter) + .Compile(); + } + } return Expression.Lambda>( self.CreateMaterializeExpression(e, "instance", materializationContextParameter), materializationContextParameter) diff --git a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs index 37f444844f0..d472f35d86e 100644 --- a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs @@ -447,7 +447,7 @@ private static Expression RemoveConvert(Expression expression) { return Expression.Lambda>( Expression.Convert(expression, typeof(object))) - .Compile() + .Compile(preferInterpretation: true) .Invoke(); } catch (Exception exception) diff --git a/src/EFCore/ValueGeneration/ValueGeneratorCache.cs b/src/EFCore/ValueGeneration/ValueGeneratorCache.cs index 04f196ad3ac..a71dd810519 100644 --- a/src/EFCore/ValueGeneration/ValueGeneratorCache.cs +++ b/src/EFCore/ValueGeneration/ValueGeneratorCache.cs @@ -27,7 +27,8 @@ namespace Microsoft.EntityFrameworkCore.ValueGeneration; /// public class ValueGeneratorCache : IValueGeneratorCache { - /// + private static readonly bool _useOldBehavior31539 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31539", out var enabled31539) && enabled31539;/// /// Initializes a new instance of the class. /// /// Parameter object containing dependencies for this service. @@ -45,25 +46,45 @@ public ValueGeneratorCache(ValueGeneratorCacheDependencies dependencies) private readonly struct CacheKey : IEquatable { - public CacheKey(IProperty property, IEntityType entityType) - { + private readonly Guid _modelId; + private readonly string? _property; + private readonly string? _entityType;public CacheKey(IProperty property, IEntityType entityType) + {if (_useOldBehavior31539) + { + _modelId = default; + _property = null; + _entityType = null; Property = property; EntityType = entityType; - } + }else + { + _modelId = entityType.Model.ModelId; + _property = property.Name; + _entityType = entityType.Name; + Property = null; + EntityType = null; + } + } - public IProperty Property { get; } + public IProperty? Property { get; } - public IEntityType EntityType { get; } + public IEntityType? EntityType { get; } public bool Equals(CacheKey other) - => Property.Equals(other.Property) && EntityType.Equals(other.EntityType); + => _useOldBehavior31539 + ? Property!.Equals(other.Property) && EntityType!.Equals(other.EntityType) + : (_property!.Equals(other._property, StringComparison.Ordinal) + && _entityType!.Equals(other._entityType, StringComparison.Ordinal) + && _modelId.Equals(other._modelId)); public override bool Equals(object? obj) => obj is CacheKey cacheKey && Equals(cacheKey); public override int GetHashCode() - => HashCode.Combine(Property, EntityType); - } + => _useOldBehavior31539 + ? HashCode.Combine(Property!, EntityType!) + : HashCode.Combine(_property!, _entityType!, _modelId); + } /// /// Gets the existing value generator from the cache, or creates a new one if one is not present in @@ -80,5 +101,6 @@ public virtual ValueGenerator GetOrAdd( IProperty property, IEntityType entityType, Func factory) - => _cache.GetOrAdd(new CacheKey(property, entityType), static (ck, f) => f(ck.Property, ck.EntityType), factory); + => _cache.GetOrAdd( + new CacheKey(property, entityType), static (ck, p) => p.factory(p.property, p.entityType), (factory, entityType, property)); } diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs index f9ff2fae314..d24c02f62d8 100644 --- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs +++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosTestStore.cs @@ -5,6 +5,11 @@ using Azure.Core; using Microsoft.Azure.Cosmos; using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Update; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using ContainerProperties = Microsoft.Azure.Cosmos.ContainerProperties; @@ -560,6 +565,9 @@ public IEnumerable> GetSeedData(bool providerValues public IEnumerable GetServiceProperties() => throw new NotImplementedException(); + public Func GetOrCreateMaterializer(IEntityMaterializerSource source) + => throw new NotImplementedException(); + public IEnumerable GetSkipNavigations() => throw new NotImplementedException(); diff --git a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs index c0013e92d6a..0465f8051a1 100644 --- a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs +++ b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Cosmos.Internal; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; namespace Microsoft.EntityFrameworkCore.Infrastructure; @@ -317,7 +320,7 @@ public virtual void Detects_missing_discriminator_value() modelBuilder.Entity().ToContainer("Orders").HasDiscriminator().HasValue(null); modelBuilder.Entity().ToContainer("Orders"); - VerifyError(CosmosStrings.NoDiscriminatorValue(typeof(Customer).Name, "Orders"), modelBuilder); + VerifyError(CoreStrings.NoDiscriminatorValue(typeof(Customer).Name), modelBuilder); } [ConditionalFact] @@ -340,7 +343,7 @@ public virtual void Passes_on_valid_concurrency_token() .Property("_etag") .IsConcurrencyToken(); - Validate(modelBuilder); + } [ConditionalFact] diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 93d29756da3..23b26005f3e 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -372,7 +372,7 @@ private static void MissingAnnotationCheck( ? validAnnotations[annotationName].Value : null); - modelBuilder.FinalizeModel(designTime: true); + modelBuilder.FinalizeModel(designTime: true, skipValidation: true); var sb = new IndentedStringBuilder(); diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs index a354af53ae0..435336628f5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerEndToEndTest.cs @@ -4,6 +4,9 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; // ReSharper disable StringStartsWithIsCultureSpecific // ReSharper disable VirtualMemberCallInConstructor diff --git a/test/EFCore.Tests/ChangeTracking/Internal/KeyPropagatorTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/KeyPropagatorTest.cs index 3c1a49f959b..464151e63a3 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/KeyPropagatorTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/KeyPropagatorTest.cs @@ -179,18 +179,17 @@ public async Task Identifying_foreign_key_value_is_generated_if_principal_key_no [InlineData(true, true)] public async Task Identifying_foreign_key_value_is_propagated_if_principal_key_is_generated(bool generateTemporary, bool async) { - var model = BuildModel(generateTemporary); - - var principal = new Product(); + var principal = new Product(); var dependent = new ProductDetail { Product = principal }; - var contextServices = CreateContextServices(model); + var contextServices = CreateContextServices(BuildModel(generateTemporary)); var stateManager = contextServices.GetRequiredService(); var principalEntry = stateManager.GetOrCreateEntry(principal); principalEntry.SetEntityState(EntityState.Added); var dependentEntry = stateManager.GetOrCreateEntry(dependent); - var principalProperty = model.FindEntityType(typeof(Product))!.FindProperty(nameof(Product.Id))!; - var dependentProperty = model.FindEntityType(typeof(ProductDetail))!.FindProperty(nameof(ProductDetail.Id))!; + var runtimeModel = contextServices.GetRequiredService(); + var principalProperty = runtimeModel.FindEntityType(typeof(Product))!.FindProperty(nameof(Product.Id))!; + var dependentProperty = runtimeModel.FindEntityType(typeof(ProductDetail))!.FindProperty(nameof(ProductDetail.Id))!; var keyPropagator = contextServices.GetRequiredService(); _ = async