diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs index be529b6071a..0c41d33e267 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs @@ -1056,7 +1056,7 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExp var valueComparer = discriminatorProperty.GetKeyValueComparer()!; var equals = valueComparer.ExtractEqualsBody( - boundProperty, + boundProperty!, Expression.Constant(derivedType.GetDiscriminatorValue(), discriminatorProperty.ClrType)); foreach (var derivedDerivedType in derivedType.GetDerivedTypes()) @@ -1064,7 +1064,7 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExp equals = Expression.OrElse( equals, valueComparer.ExtractEqualsBody( - boundProperty, + boundProperty!, Expression.Constant(derivedDerivedType.GetDiscriminatorValue(), discriminatorProperty.ClrType))); } diff --git a/src/EFCore/ChangeTracking/ArrayStructuralComparer.cs b/src/EFCore/ChangeTracking/ArrayStructuralComparer.cs index a3937a904d3..806feee64d3 100644 --- a/src/EFCore/ChangeTracking/ArrayStructuralComparer.cs +++ b/src/EFCore/ChangeTracking/ArrayStructuralComparer.cs @@ -3,6 +3,8 @@ using System.Linq; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/CascadeTiming.cs b/src/EFCore/ChangeTracking/CascadeTiming.cs index 26e7e0b81ef..da99458a0f7 100644 --- a/src/EFCore/ChangeTracking/CascadeTiming.cs +++ b/src/EFCore/ChangeTracking/CascadeTiming.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/ChangeTracker.cs b/src/EFCore/ChangeTracking/ChangeTracker.cs index 2f50b65adb7..2803dc66784 100644 --- a/src/EFCore/ChangeTracking/ChangeTracker.cs +++ b/src/EFCore/ChangeTracking/ChangeTracker.cs @@ -14,6 +14,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -283,7 +285,7 @@ public virtual void TrackGraph( return false; } - n.NodeState(n); + n.NodeState!(n); return n.Entry.State != EntityState.Detached; }); @@ -452,7 +454,7 @@ public virtual DebugView DebugView /// /// A string that represents the current object. [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() + public override string? ToString() => base.ToString(); /// @@ -461,7 +463,7 @@ public override string ToString() /// The object to compare with the current object. /// if the specified object is equal to the current object; otherwise, . [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) + public override bool Equals(object? obj) => base.Equals(obj); /// diff --git a/src/EFCore/ChangeTracking/ChangeTrackerDebugStringOptions.cs b/src/EFCore/ChangeTracking/ChangeTrackerDebugStringOptions.cs index b51d30aebd5..a5279d848ae 100644 --- a/src/EFCore/ChangeTracking/ChangeTrackerDebugStringOptions.cs +++ b/src/EFCore/ChangeTracking/ChangeTrackerDebugStringOptions.cs @@ -3,6 +3,8 @@ using System; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/ChangeTrackerExtensions.cs b/src/EFCore/ChangeTracking/ChangeTrackerExtensions.cs index 2e8e9330d82..48e715df31d 100644 --- a/src/EFCore/ChangeTracking/ChangeTrackerExtensions.cs +++ b/src/EFCore/ChangeTracking/ChangeTrackerExtensions.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore { @@ -53,8 +55,23 @@ private sealed class EntityEntryComparer : IComparer { public static readonly EntityEntryComparer Instance = new(); - public int Compare(InternalEntityEntry x, InternalEntityEntry y) + public int Compare(InternalEntityEntry? x, InternalEntityEntry? y) { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + var result = StringComparer.InvariantCulture.Compare(x.EntityType.Name, y.EntityType.Name); if (result != 0) { diff --git a/src/EFCore/ChangeTracking/CollectionEntry.cs b/src/EFCore/ChangeTracking/CollectionEntry.cs index 031dae40023..0948e1747c8 100644 --- a/src/EFCore/ChangeTracking/CollectionEntry.cs +++ b/src/EFCore/ChangeTracking/CollectionEntry.cs @@ -13,6 +13,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -27,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking /// public class CollectionEntry : NavigationEntry { - private ICollectionLoader _loader; + private ICollectionLoader? _loader; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -81,9 +83,9 @@ private void LocalDetectChanges() /// the change tracker is aware of the change and is not required /// for the context to detect the change. /// - public new virtual IEnumerable CurrentValue + public new virtual IEnumerable? CurrentValue { - get => (IEnumerable)base.CurrentValue; + get => (IEnumerable?)base.CurrentValue; [param: CanBeNull] set => base.CurrentValue = value; } @@ -254,14 +256,14 @@ public override IQueryable Query() } private void EnsureInitialized() - => Metadata.GetCollectionAccessor().GetOrCreate(InternalEntry.Entity, forMaterialization: true); + => Metadata.GetCollectionAccessor()!.GetOrCreate(InternalEntry.Entity, forMaterialization: true); /// /// The of an entity this navigation targets. /// /// The entity to get the entry for. /// An entry for an entity that this navigation targets. - public virtual EntityEntry FindEntry([NotNull] object entity) + public virtual EntityEntry? FindEntry([NotNull] object entity) { var entry = GetInternalTargetEntry(entity); return entry == null @@ -276,9 +278,9 @@ public virtual EntityEntry FindEntry([NotNull] object entity) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - protected virtual InternalEntityEntry GetInternalTargetEntry([NotNull] object entity) + protected virtual InternalEntityEntry? GetInternalTargetEntry([NotNull] object entity) => CurrentValue == null - || !Metadata.GetCollectionAccessor().Contains(InternalEntry.Entity, entity) + || !Metadata.GetCollectionAccessor()!.Contains(InternalEntry.Entity, entity) ? null : InternalEntry.StateManager.GetOrCreateEntry(entity, Metadata.TargetEntityType); diff --git a/src/EFCore/ChangeTracking/CollectionEntry`.cs b/src/EFCore/ChangeTracking/CollectionEntry`.cs index 380eee2613f..49813f4c1aa 100644 --- a/src/EFCore/ChangeTracking/CollectionEntry`.cs +++ b/src/EFCore/ChangeTracking/CollectionEntry`.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -62,7 +64,7 @@ public CollectionEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IN /// the change tracker is aware of the change and is not required /// for the context to detect the change. /// - public new virtual IEnumerable CurrentValue + public new virtual IEnumerable? CurrentValue { get => this.GetInfrastructure().GetCurrentValue>(Metadata); [param: CanBeNull] set => base.CurrentValue = value; @@ -90,7 +92,7 @@ public CollectionEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IN /// /// The entity to get the entry for. /// An entry for an entity that this navigation targets. - public new virtual EntityEntry FindEntry([NotNull] object entity) + public new virtual EntityEntry? FindEntry([NotNull] object entity) { var entry = GetInternalTargetEntry(entity); return entry == null diff --git a/src/EFCore/ChangeTracking/EntityEntry.cs b/src/EFCore/ChangeTracking/EntityEntry.cs index 6ebbf863749..ccc8020a105 100644 --- a/src/EFCore/ChangeTracking/EntityEntry.cs +++ b/src/EFCore/ChangeTracking/EntityEntry.cs @@ -18,6 +18,8 @@ using Microsoft.EntityFrameworkCore.Update; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -33,7 +35,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking public class EntityEntry : IInfrastructure { private static readonly int _maxEntityState = Enum.GetValues(typeof(EntityState)).Cast().Max(); - private IEntityFinder _finder; + private IEntityFinder? _finder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -146,7 +148,7 @@ public virtual MemberEntry Member([NotNull] string propertyName) return new PropertyEntry(InternalEntry, propertyName); } - var navigation = (INavigationBase)InternalEntry.EntityType.FindNavigation(propertyName) + var navigation = (INavigationBase?)InternalEntry.EntityType.FindNavigation(propertyName) ?? InternalEntry.EntityType.FindSkipNavigation(propertyName); if (navigation != null) { @@ -176,7 +178,7 @@ public virtual NavigationEntry Navigation([NotNull] string propertyName) { Check.NotEmpty(propertyName, nameof(propertyName)); - var navigation = (INavigationBase)InternalEntry.EntityType.FindNavigation(propertyName) + var navigation = (INavigationBase?)InternalEntry.EntityType.FindNavigation(propertyName) ?? InternalEntry.EntityType.FindSkipNavigation(propertyName); if (navigation != null) @@ -345,7 +347,7 @@ public virtual PropertyValues OriginalValues /// /// /// The store values, or null if the entity does not exist in the database. - public virtual PropertyValues GetDatabaseValues() + public virtual PropertyValues? GetDatabaseValues() { var values = Finder.GetDatabaseValues(InternalEntry); @@ -372,7 +374,7 @@ public virtual PropertyValues GetDatabaseValues() /// or if the entity does not exist in the database. /// /// If the is canceled. - public virtual async Task GetDatabaseValuesAsync(CancellationToken cancellationToken = default) + public virtual async Task GetDatabaseValuesAsync(CancellationToken cancellationToken = default) { var values = await Finder.GetDatabaseValuesAsync(InternalEntry, cancellationToken) .ConfigureAwait(false); @@ -413,7 +415,7 @@ public virtual void Reload() public virtual async Task ReloadAsync(CancellationToken cancellationToken = default) => Reload(await GetDatabaseValuesAsync(cancellationToken).ConfigureAwait(false)); - private void Reload(PropertyValues storeValues) + private void Reload(PropertyValues? storeValues) { if (storeValues == null) { @@ -463,7 +465,7 @@ public virtual DebugView DebugView /// The object to compare with the current object. /// if the specified object is equal to the current object; otherwise, . [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) + public override bool Equals(object? obj) => base.Equals(obj); /// diff --git a/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs b/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs index 59eb18e443e..dc171cf2faa 100644 --- a/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs +++ b/src/EFCore/ChangeTracking/EntityEntryEventArgs.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -14,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking public class EntityEntryEventArgs : EventArgs { private readonly InternalEntityEntry _internalEntityEntry; - private EntityEntry _entry; + private EntityEntry? _entry; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/EntityEntryGraphNode.cs b/src/EFCore/ChangeTracking/EntityEntryGraphNode.cs index d50056a71a6..5c53e65204c 100644 --- a/src/EFCore/ChangeTracking/EntityEntryGraphNode.cs +++ b/src/EFCore/ChangeTracking/EntityEntryGraphNode.cs @@ -8,6 +8,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -22,7 +26,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking public class EntityEntryGraphNode : IInfrastructure { private readonly InternalEntityEntry _entry; - private readonly InternalEntityEntry _sourceEntry; + private readonly InternalEntityEntry? _sourceEntry; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -34,8 +38,8 @@ public class EntityEntryGraphNode : IInfrastructure [EntityFrameworkInternal] public EntityEntryGraphNode( [NotNull] InternalEntityEntry entry, - [CanBeNull] InternalEntityEntry sourceEntry, - [CanBeNull] INavigationBase inboundNavigation) + [CanBeNull] InternalEntityEntry? sourceEntry, + [CanBeNull] INavigationBase? inboundNavigation) { Check.NotNull(entry, nameof(entry)); @@ -53,7 +57,7 @@ public EntityEntryGraphNode( /// See for information on how graph nodes are used. /// /// - public virtual EntityEntry SourceEntry + public virtual EntityEntry? SourceEntry => _sourceEntry == null ? null : new EntityEntry(_sourceEntry); /// @@ -64,7 +68,8 @@ public virtual EntityEntry SourceEntry /// See for information on how graph nodes are used. /// /// - public virtual INavigationBase InboundNavigation { get; } + [CA.MemberNotNull("SourceEntry")] + public virtual INavigationBase? InboundNavigation { get; } /// /// diff --git a/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs b/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs index 33961b7b2af..bd297ec6463 100644 --- a/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs +++ b/src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -26,9 +28,9 @@ public class EntityEntryGraphNode : EntityEntryGraphNode [EntityFrameworkInternal] public EntityEntryGraphNode( [NotNull] InternalEntityEntry entry, - [CanBeNull] TState state, - [CanBeNull] InternalEntityEntry sourceEntry, - [CanBeNull] INavigationBase inboundNavigation) + [CanBeNull] TState? state, + [CanBeNull] InternalEntityEntry? sourceEntry, + [CanBeNull] INavigationBase? inboundNavigation) : base(entry, sourceEntry, inboundNavigation) { NodeState = state; @@ -37,7 +39,7 @@ public EntityEntryGraphNode( /// /// Gets or sets state that will be available to all nodes that are visited after this node. /// - public virtual TState NodeState { get; [param: CanBeNull] set; } + public virtual TState? NodeState { get; [param: CanBeNull] set; } /// /// Creates a new node for the entity that is being traversed next in the graph. diff --git a/src/EFCore/ChangeTracking/EntityEntry`.cs b/src/EFCore/ChangeTracking/EntityEntry`.cs index 9d604c845ff..4b07cf1d557 100644 --- a/src/EFCore/ChangeTracking/EntityEntry`.cs +++ b/src/EFCore/ChangeTracking/EntityEntry`.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -155,7 +157,7 @@ public virtual PropertyEntry Property( return new PropertyEntry(InternalEntry, propertyName); } - private static void ValidateType(IProperty property) + private static void ValidateType(IProperty? property) { if (property != null && property.ClrType != typeof(TProperty)) diff --git a/src/EFCore/ChangeTracking/EntityStateChangedEventArgs.cs b/src/EFCore/ChangeTracking/EntityStateChangedEventArgs.cs index b10d4d9c338..90c919e79d4 100644 --- a/src/EFCore/ChangeTracking/EntityStateChangedEventArgs.cs +++ b/src/EFCore/ChangeTracking/EntityStateChangedEventArgs.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs b/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs index f2512ec51a4..c60cd029953 100644 --- a/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs +++ b/src/EFCore/ChangeTracking/EntityTrackedEventArgs.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/EntryCurrentValueComparer`.cs b/src/EFCore/ChangeTracking/EntryCurrentValueComparer`.cs index b4c94b1f6fb..190d2665a6f 100644 --- a/src/EFCore/ChangeTracking/EntryCurrentValueComparer`.cs +++ b/src/EFCore/ChangeTracking/EntryCurrentValueComparer`.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -41,10 +43,27 @@ public EntryCurrentValueComparer([NotNull] IPropertyBase property) /// The first object to compare. /// The second object to compare. /// A negative number if 'x' is less than 'y'; a positive number if 'x' is greater than 'y'; zero otherwise. - public int Compare(IUpdateEntry x, IUpdateEntry y) - => _underlyingComparer.Compare( + public int Compare(IUpdateEntry? x, IUpdateEntry? y) + { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + + return _underlyingComparer.Compare( x.GetCurrentValue(_property), y.GetCurrentValue(_property)); + } /// /// Determines whether the specified objects are equal. @@ -52,7 +71,7 @@ public int Compare(IUpdateEntry x, IUpdateEntry y) /// The first object to compare. /// The second object to compare. /// if the specified objects are equal; otherwise, . - public bool Equals(IUpdateEntry x, IUpdateEntry y) + public bool Equals(IUpdateEntry? x, IUpdateEntry? y) => Compare(x, y) == 0; /// @@ -61,6 +80,6 @@ public bool Equals(IUpdateEntry x, IUpdateEntry y) /// The for which a hash code is to be returned. /// A hash code for the specified object. public int GetHashCode(IUpdateEntry obj) - => obj.GetCurrentValue(_property).GetHashCode(); + => obj.GetCurrentValue(_property)?.GetHashCode() ?? 0; } } diff --git a/src/EFCore/ChangeTracking/GeometryValueComparer.cs b/src/EFCore/ChangeTracking/GeometryValueComparer.cs index 0fecbc064bb..a801a67f07a 100644 --- a/src/EFCore/ChangeTracking/GeometryValueComparer.cs +++ b/src/EFCore/ChangeTracking/GeometryValueComparer.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using System.Reflection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -23,7 +25,7 @@ public GeometryValueComparer() { } - private static Expression> GetEqualsExpression() + private static Expression> GetEqualsExpression() { var left = Expression.Parameter(typeof(TGeometry), "left"); var right = Expression.Parameter(typeof(TGeometry), "right"); @@ -34,7 +36,7 @@ private static Expression> GetEqualsExpression( var yNull = Expression.Variable(typeof(bool), "yNull"); var nullExpression = Expression.Constant(null, typeof(TGeometry)); - return Expression.Lambda>( + return Expression.Lambda>( Expression.Block( typeof(bool), new[] { x, y, xNull, yNull }, @@ -50,26 +52,26 @@ private static Expression> GetEqualsExpression( Expression.IsFalse(yNull), Expression.Call( x, - typeof(TGeometry).GetRuntimeMethod("EqualsExact", new[] { typeof(TGeometry) }), + typeof(TGeometry).GetRequiredRuntimeMethod("EqualsExact", new[] { typeof(TGeometry) }), y))))), left, right); } - private static Expression> GetSnapshotExpression() + private static Expression> GetSnapshotExpression() { var instance = Expression.Parameter(typeof(TGeometry), "instance"); Expression body = Expression.Call( instance, - typeof(TGeometry).GetRuntimeMethod("Copy", Type.EmptyTypes)); + typeof(TGeometry).GetRequiredRuntimeMethod("Copy", Type.EmptyTypes)); if (typeof(TGeometry).FullName != "NetTopologySuite.Geometries.Geometry") { body = Expression.Convert(body, typeof(TGeometry)); } - return Expression.Lambda>(body, instance); + return Expression.Lambda>(body, instance); } } } diff --git a/src/EFCore/ChangeTracking/IDependentKeyValueFactory.cs b/src/EFCore/ChangeTracking/IDependentKeyValueFactory.cs index 9dbba4a6398..7a658ace685 100644 --- a/src/EFCore/ChangeTracking/IDependentKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/IDependentKeyValueFactory.cs @@ -6,6 +6,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -27,7 +31,7 @@ public interface IDependentKeyValueFactory /// The key instance. /// if the key instance was created; otherwise. [ContractAnnotation("=>true, key:notnull; =>false, key:null")] - bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key); + bool TryCreateFromBuffer(in ValueBuffer valueBuffer, [CA.NotNullWhen(true)] out TKey? key); /// /// Attempts to create a key instance using foreign key values from the given . @@ -36,7 +40,7 @@ public interface IDependentKeyValueFactory /// The key instance. /// if the key instance was created; otherwise. [ContractAnnotation("=>true, key:notnull; =>false, key:null")] - bool TryCreateFromCurrentValues([NotNull] IUpdateEntry entry, out TKey key); + bool TryCreateFromCurrentValues([NotNull] IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key); /// /// Attempts to create a key instance from the given @@ -46,7 +50,7 @@ public interface IDependentKeyValueFactory /// The key instance. /// if the key instance was created; otherwise. [ContractAnnotation("=>true, key:notnull; =>false, key:null")] - bool TryCreateFromPreStoreGeneratedCurrentValues([NotNull] IUpdateEntry entry, out TKey key); + bool TryCreateFromPreStoreGeneratedCurrentValues([NotNull] IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key); /// /// Attempts to create a key instance using original foreign key values from the given . @@ -55,7 +59,7 @@ public interface IDependentKeyValueFactory /// The key instance. /// if the key instance was created; otherwise. [ContractAnnotation("=>true, key:notnull; =>false, key:null")] - bool TryCreateFromOriginalValues([NotNull] IUpdateEntry entry, out TKey key); + bool TryCreateFromOriginalValues([NotNull] IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key); /// /// Attempts to create a key instance from the given @@ -65,7 +69,7 @@ public interface IDependentKeyValueFactory /// The key instance. /// if the key instance was created; otherwise. [ContractAnnotation("=>true, key:notnull; =>false, key:null")] - bool TryCreateFromRelationshipSnapshot([NotNull] IUpdateEntry entry, out TKey key); + bool TryCreateFromRelationshipSnapshot([NotNull] IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key); /// /// The to use for comparing key instances. diff --git a/src/EFCore/ChangeTracking/IEntityEntryGraphIterator.cs b/src/EFCore/ChangeTracking/IEntityEntryGraphIterator.cs index a80d7a862ac..ce65070e7bd 100644 --- a/src/EFCore/ChangeTracking/IEntityEntryGraphIterator.cs +++ b/src/EFCore/ChangeTracking/IEntityEntryGraphIterator.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// diff --git a/src/EFCore/ChangeTracking/IPrincipalKeyValueFactory.cs b/src/EFCore/ChangeTracking/IPrincipalKeyValueFactory.cs index 84bf39ad2fa..12ab6cb3e5d 100644 --- a/src/EFCore/ChangeTracking/IPrincipalKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/IPrincipalKeyValueFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -26,49 +28,49 @@ public interface IPrincipalKeyValueFactory /// /// The key values. /// The key object, or null if any of the key values were null. - object CreateFromKeyValues([NotNull] object[] keyValues); + object? CreateFromKeyValues([NotNull] object?[] keyValues); /// /// Creates a key object from key values obtained from their indexed position in the given . /// /// The buffer containing key values. /// The key object, or null if any of the key values were null. - object CreateFromBuffer(ValueBuffer valueBuffer); + object? CreateFromBuffer(ValueBuffer valueBuffer); /// /// Finds the first null in the given in-order array of key values and returns the associated . /// /// The key values. /// The associated property. - IProperty FindNullPropertyInKeyValues([NotNull] object[] keyValues); + IProperty? FindNullPropertyInKeyValues([NotNull] object?[] keyValues); /// /// Creates a key object from the key values in the given entry. /// /// The entry tracking an entity instance. /// The key value. - TKey CreateFromCurrentValues([NotNull] IUpdateEntry entry); + TKey? CreateFromCurrentValues([NotNull] IUpdateEntry entry); /// /// Finds the first null key value in the given entry and returns the associated . /// /// The entry tracking an entity instance. /// The associated property. - IProperty FindNullPropertyInCurrentValues([NotNull] IUpdateEntry entry); + IProperty? FindNullPropertyInCurrentValues([NotNull] IUpdateEntry entry); /// /// Creates a key object from the original key values in the given entry. /// /// The entry tracking an entity instance. /// The key value. - TKey CreateFromOriginalValues([NotNull] IUpdateEntry entry); + TKey? CreateFromOriginalValues([NotNull] IUpdateEntry entry); /// /// Creates a key object from the relationship snapshot key values in the given entry. /// /// The entry tracking an entity instance. /// The key value. - TKey CreateFromRelationshipSnapshot([NotNull] IUpdateEntry entry); + TKey? CreateFromRelationshipSnapshot([NotNull] IUpdateEntry entry); /// /// An for comparing key objects. diff --git a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs index 9796a9c98c2..48b7ea2fbdf 100644 --- a/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/ArrayPropertyValues.cs @@ -13,6 +13,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -23,8 +25,8 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// public class ArrayPropertyValues : PropertyValues { - private readonly object[] _values; - private IReadOnlyList _properties; + private readonly object?[] _values; + private IReadOnlyList? _properties; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -32,7 +34,7 @@ public class ArrayPropertyValues : PropertyValues /// 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 ArrayPropertyValues([NotNull] InternalEntityEntry internalEntry, [NotNull] object[] values) + public ArrayPropertyValues([NotNull] InternalEntityEntry internalEntry, [NotNull] object?[] values) : base(internalEntry) => _values = values; @@ -118,7 +120,7 @@ public override void SetValues(PropertyValues propertyValues) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public override IReadOnlyList Properties - => _properties ?? (_properties = EntityType.GetProperties().ToList()); + => _properties ??= EntityType.GetProperties().ToList(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -126,7 +128,7 @@ public override IReadOnlyList Properties /// 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 override object this[string propertyName] + public override object? this[string propertyName] { get => _values[EntityType.GetProperty(propertyName).GetIndex()]; set => SetValue(EntityType.GetProperty(propertyName).GetIndex(), value); @@ -138,7 +140,7 @@ public override object this[string propertyName] /// 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 override object this[IProperty property] + public override object? this[IProperty property] { get => _values[EntityType.CheckPropertyBelongsToType(property).GetIndex()]; set => SetValue(EntityType.CheckPropertyBelongsToType(property).GetIndex(), value); @@ -150,8 +152,9 @@ public override object this[IProperty property] /// 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 override TValue GetValue(string propertyName) - => (TValue)this[propertyName]; + public override TValue? GetValue(string propertyName) + where TValue: default + => (TValue?)this[propertyName]; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -159,10 +162,11 @@ public override TValue GetValue(string propertyName) /// 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 override TValue GetValue(IProperty property) - => (TValue)this[property]; + public override TValue? GetValue(IProperty property) + where TValue : default + => (TValue?)this[property]; - private void SetValue(int index, object value) + private void SetValue(int index, object? value) { var property = Properties[index]; diff --git a/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs b/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs index 91e862b2d89..f89651808e1 100644 --- a/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs +++ b/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs @@ -13,6 +13,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -257,7 +259,7 @@ void SetPropertyModified() } } - private void LogChangeDetected(InternalEntityEntry entry, IProperty property, object original, object current) + private void LogChangeDetected(InternalEntityEntry entry, IProperty property, object? original, object? current) { if (_loggingOptions.IsSensitiveDataLoggingEnabled) { @@ -312,8 +314,8 @@ private void DetectNavigationChange(InternalEntityEntry entry, INavigationBase n if (navigationBase.IsCollection) { - var snapshotCollection = (IEnumerable)snapshotValue; - var currentCollection = (IEnumerable)currentValue; + var snapshotCollection = (IEnumerable?)snapshotValue; + var currentCollection = (IEnumerable?)currentValue; var removed = new HashSet(LegacyReferenceEqualityComparer.Instance); if (snapshotCollection != null) @@ -378,7 +380,7 @@ private void DetectNavigationChange(InternalEntityEntry entry, INavigationBase n { _logger.ReferenceChangeDetected(entry, navigation, snapshotValue, currentValue); } - + stateManager.InternalEntityEntryNotifier.NavigationReferenceChanged(entry, navigation, snapshotValue, currentValue); } } diff --git a/src/EFCore/ChangeTracking/Internal/ChangeTrackerFactory.cs b/src/EFCore/ChangeTracking/Internal/ChangeTrackerFactory.cs index b6bd89481bd..c3b3ce9f9c2 100644 --- a/src/EFCore/ChangeTracking/Internal/ChangeTrackerFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/ChangeTrackerFactory.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs index ab167895093..99b929e379f 100644 --- a/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/CompositePrincipalKeyValueFactory.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -35,7 +37,7 @@ public CompositePrincipalKeyValueFactory([NotNull] IKey key) /// 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 object CreateFromKeyValues(object[] keyValues) + public virtual object? CreateFromKeyValues(object?[] keyValues) => keyValues.Any(v => v == null) ? null : keyValues; /// @@ -44,7 +46,7 @@ public virtual object CreateFromKeyValues(object[] keyValues) /// 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 object CreateFromBuffer(ValueBuffer valueBuffer) + public virtual object? CreateFromBuffer(ValueBuffer valueBuffer) => TryCreateFromBuffer(valueBuffer, out var values) ? values : null; /// @@ -53,7 +55,7 @@ public virtual object CreateFromBuffer(ValueBuffer valueBuffer) /// 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 IProperty FindNullPropertyInKeyValues(object[] keyValues) + public virtual IProperty FindNullPropertyInKeyValues(object?[] keyValues) { var index = -1; for (var i = 0; i < keyValues.Length; i++) @@ -74,7 +76,7 @@ public virtual IProperty FindNullPropertyInKeyValues(object[] keyValues) /// 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 object[] CreateFromCurrentValues(IUpdateEntry entry) + public virtual object[]? CreateFromCurrentValues(IUpdateEntry entry) => CreateFromEntry(entry, (e, p) => e.GetCurrentValue(p)); /// @@ -83,7 +85,7 @@ public virtual object[] CreateFromCurrentValues(IUpdateEntry entry) /// 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 IProperty FindNullPropertyInCurrentValues(IUpdateEntry entry) + public virtual IProperty? FindNullPropertyInCurrentValues(IUpdateEntry entry) => Properties.FirstOrDefault(p => entry.GetCurrentValue(p) == null); /// @@ -92,7 +94,7 @@ public virtual IProperty FindNullPropertyInCurrentValues(IUpdateEntry entry) /// 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 object[] CreateFromOriginalValues(IUpdateEntry entry) + public virtual object[]? CreateFromOriginalValues(IUpdateEntry entry) => CreateFromEntry(entry, (e, p) => e.GetOriginalValue(p)); /// @@ -101,22 +103,24 @@ public virtual object[] CreateFromOriginalValues(IUpdateEntry entry) /// 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 object[] CreateFromRelationshipSnapshot(IUpdateEntry entry) + public virtual object[]? CreateFromRelationshipSnapshot(IUpdateEntry entry) => CreateFromEntry(entry, (e, p) => e.GetRelationshipSnapshotValue(p)); - private object[] CreateFromEntry( + private object[]? CreateFromEntry( IUpdateEntry entry, - Func getValue) + Func getValue) { var values = new object[Properties.Count]; var index = 0; foreach (var property in Properties) { - if ((values[index++] = getValue(entry, property)) == null) + var value = getValue(entry, property); + if (value == null) { return null; } + values[index++] = value; } return values; diff --git a/src/EFCore/ChangeTracking/Internal/CompositeValueFactory.cs b/src/EFCore/ChangeTracking/Internal/CompositeValueFactory.cs index d7e23ead69a..7eabe254f14 100644 --- a/src/EFCore/ChangeTracking/Internal/CompositeValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/CompositeValueFactory.cs @@ -10,6 +10,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -54,18 +58,21 @@ public CompositeValueFactory([NotNull] IReadOnlyList properties) /// 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 bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out object[] key) + public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, [CA.NotNullWhen(true)] out object[]? key) { key = new object[Properties.Count]; var index = 0; foreach (var property in Properties) { - if ((key[index++] = valueBuffer[property.GetIndex()]) == null) + var value = valueBuffer[property.GetIndex()]; + if (value == null) { key = null; return false; } + + key[index++] = value; } return true; @@ -77,7 +84,7 @@ public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out object[] /// 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 bool TryCreateFromCurrentValues(IUpdateEntry entry, out object[] key) + public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out object[]? key) => TryCreateFromEntry(entry, (e, p) => e.GetCurrentValue(p), out key); /// @@ -86,7 +93,7 @@ public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, out object[] /// 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 bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, out object[] key) + public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out object[]? key) => TryCreateFromEntry(entry, (e, p) => e.GetPreStoreGeneratedCurrentValue(p), out key); /// @@ -95,7 +102,7 @@ public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry ent /// 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 bool TryCreateFromOriginalValues(IUpdateEntry entry, out object[] key) + public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out object[]? key) => TryCreateFromEntry(entry, (e, p) => e.GetOriginalValue(p), out key); /// @@ -104,7 +111,7 @@ public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, out object[] /// 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 bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, out object[] key) + public virtual bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, [CA.NotNullWhen(true)] out object[]? key) => TryCreateFromEntry(entry, (e, p) => e.GetRelationshipSnapshotValue(p), out key); /// @@ -115,19 +122,22 @@ public virtual bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, out ob /// protected virtual bool TryCreateFromEntry( [NotNull] IUpdateEntry entry, - [NotNull] Func getValue, - out object[] key) + [NotNull] Func getValue, + [CA.NotNullWhen(true)] out object[]? key) { key = new object[Properties.Count]; var index = 0; foreach (var property in Properties) { - if ((key[index++] = getValue(entry, property)) == null) + var value = getValue(entry, property); + if (value == null) { key = null; return false; } + + key[index++] = value; } return true; @@ -141,7 +151,7 @@ protected virtual bool TryCreateFromEntry( /// protected static IEqualityComparer CreateEqualityComparer([NotNull] IReadOnlyList properties) { - var comparers = properties.Select(p => p.GetKeyValueComparer()).ToList(); + var comparers = properties.Select(p => p.GetKeyValueComparer()!).ToList(); return comparers.All(c => c != null) ? new CompositeCustomComparer(comparers) @@ -161,13 +171,23 @@ public CompositeCustomComparer(IList comparers) _hashCodes = comparers.Select(c => (Func)c.GetHashCode).ToArray(); } - public bool Equals(object[] x, object[] y) + public bool Equals(object[]? x, object[]? y) { if (ReferenceEquals(x, y)) { return true; } + if (x is null) + { + return y is null; + } + + if (y is null) + { + return false; + } + if (x.Length != y.Length) { return false; @@ -201,13 +221,23 @@ public int GetHashCode(object[] obj) private sealed class CompositeComparer : IEqualityComparer { - public bool Equals(object[] x, object[] y) + public bool Equals(object[]? x, object[]? y) { if (ReferenceEquals(x, y)) { return true; } + if (x is null) + { + return y is null; + } + + if (y is null) + { + return false; + } + if (x.Length != y.Length) { return false; @@ -241,13 +271,23 @@ private sealed class StructuralCompositeComparer : IEqualityComparer private readonly IEqualityComparer _structuralEqualityComparer = StructuralComparisons.StructuralEqualityComparer; - public bool Equals(object[] x, object[] y) + public bool Equals(object[]? x, object[]? y) { if (ReferenceEquals(x, y)) { return true; } + if (x is null) + { + return y is null; + } + + if (y is null) + { + return false; + } + if (x.Length != y.Length) { return false; diff --git a/src/EFCore/ChangeTracking/Internal/CurrentPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/CurrentPropertyValues.cs index 0f4c897b1ca..227b7244f9e 100644 --- a/src/EFCore/ChangeTracking/Internal/CurrentPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/CurrentPropertyValues.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -32,7 +34,8 @@ public CurrentPropertyValues([NotNull] InternalEntityEntry internalEntry) /// 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 override TValue GetValue(string propertyName) + public override TValue? GetValue(string propertyName) + where TValue : default => InternalEntry.GetCurrentValue(InternalEntry.EntityType.GetProperty(propertyName)); /// @@ -41,7 +44,8 @@ public override TValue GetValue(string propertyName) /// 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 override TValue GetValue(IProperty property) + public override TValue? GetValue(IProperty property) + where TValue : default => InternalEntry.GetCurrentValue(InternalEntry.EntityType.CheckPropertyBelongsToType(property)); /// @@ -50,7 +54,7 @@ public override TValue GetValue(IProperty property) /// 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 override void SetValueInternal(IProperty property, object value) + protected override void SetValueInternal(IProperty property, object? value) => InternalEntry[property] = value; /// @@ -59,7 +63,7 @@ protected override void SetValueInternal(IProperty property, object value) /// 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 override object GetValueInternal(IProperty property) + protected override object? GetValueInternal(IProperty property) => InternalEntry[property]; } } diff --git a/src/EFCore/ChangeTracking/Internal/CurrentProviderValueComparer`.cs b/src/EFCore/ChangeTracking/Internal/CurrentProviderValueComparer`.cs index 2bdf6df81e8..a898c34bbb5 100644 --- a/src/EFCore/ChangeTracking/Internal/CurrentProviderValueComparer`.cs +++ b/src/EFCore/ChangeTracking/Internal/CurrentProviderValueComparer`.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -43,9 +45,27 @@ public CurrentProviderValueComparer( /// 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 int Compare(IUpdateEntry x, IUpdateEntry y) - => _underlyingComparer.Compare( - _converter(x.GetCurrentValue(_property)), - _converter(y.GetCurrentValue(_property))); + public virtual int Compare(IUpdateEntry? x, IUpdateEntry? y) + { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + + // TODO-NULLABLE: ValueConverters with null + return _underlyingComparer.Compare( + _converter(x.GetCurrentValue(_property)!), + _converter(y.GetCurrentValue(_property)!)); + } } } diff --git a/src/EFCore/ChangeTracking/Internal/CurrentValueComparerFactory.cs b/src/EFCore/ChangeTracking/Internal/CurrentValueComparerFactory.cs index 5225104e2d2..78123ffffbc 100644 --- a/src/EFCore/ChangeTracking/Internal/CurrentValueComparerFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/CurrentValueComparerFactory.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -34,7 +36,7 @@ public virtual IComparer Create([NotNull] IPropertyBase propertyBa { return (IComparer)Activator.CreateInstance( typeof(EntryCurrentValueComparer<>).MakeGenericType(modelType), - propertyBase); + propertyBase)!; } if (typeof(IStructuralComparable).IsAssignableFrom(nonNullableModelType)) @@ -63,7 +65,7 @@ public virtual IComparer Create([NotNull] IPropertyBase propertyBa : typeof(NullableStructCurrentProviderValueComparer<,>).MakeGenericType( nonNullableModelType, converter.ProviderClrType); - return (IComparer)Activator.CreateInstance(comparerType, propertyBase, converter); + return (IComparer)Activator.CreateInstance(comparerType, propertyBase, converter)!; } if (typeof(IStructuralComparable).IsAssignableFrom(nonNullableProviderType)) @@ -91,7 +93,7 @@ public virtual IComparer Create([NotNull] IPropertyBase propertyBa propertyBase.Name, modelType.ShortDisplayName())); - bool IsGenericComparable(Type type, Type nonNullableType) + static bool IsGenericComparable(Type type, Type nonNullableType) => typeof(IComparable<>).MakeGenericType(type).IsAssignableFrom(type) || typeof(IComparable<>).MakeGenericType(nonNullableType).IsAssignableFrom(nonNullableType) || type.IsEnum diff --git a/src/EFCore/ChangeTracking/Internal/DependentKeyValueFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/DependentKeyValueFactoryFactory.cs index e2b2a993116..6b47669df29 100644 --- a/src/EFCore/ChangeTracking/Internal/DependentKeyValueFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/DependentKeyValueFactoryFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -50,13 +52,13 @@ public virtual IDependentKeyValueFactory CreateSimple([NotNull] IFor { return (IDependentKeyValueFactory)Activator.CreateInstance( typeof(SimpleNullableDependentKeyValueFactory<>).MakeGenericType( - typeof(TKey)), dependentProperty, propertyAccessors); + typeof(TKey)), dependentProperty, propertyAccessors)!; } return principalType.IsNullableType() ? (IDependentKeyValueFactory)Activator.CreateInstance( typeof(SimpleNullablePrincipalDependentKeyValueFactory<,>).MakeGenericType( - typeof(TKey), typeof(TKey).UnwrapNullableType()), dependentProperty, propertyAccessors) + typeof(TKey), typeof(TKey).UnwrapNullableType()), dependentProperty, propertyAccessors)! : new SimpleNonNullableDependentKeyValueFactory(dependentProperty, propertyAccessors); } diff --git a/src/EFCore/ChangeTracking/Internal/DependentsMap.cs b/src/EFCore/ChangeTracking/Internal/DependentsMap.cs index ae1425489e7..b977e7b9895 100644 --- a/src/EFCore/ChangeTracking/Internal/DependentsMap.cs +++ b/src/EFCore/ChangeTracking/Internal/DependentsMap.cs @@ -7,6 +7,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -16,6 +20,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class DependentsMap : IDependentsMap + where TKey : notnull { private readonly IForeignKey _foreignKey; private readonly IPrincipalKeyValueFactory _principalKeyValueFactory; @@ -107,7 +112,7 @@ public virtual void Update(IUpdateEntry entry) } } - private bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) + private bool TryCreateFromCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { // TODO: Move into delegate foreach (var property in _foreignKey.Properties) @@ -130,7 +135,7 @@ private bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) /// public virtual IEnumerable GetDependents(IUpdateEntry principalEntry) { - return _map.TryGetValue(_principalKeyValueFactory.CreateFromCurrentValues(principalEntry), out var dependents) + return _map.TryGetValue(_principalKeyValueFactory.CreateFromCurrentValues(principalEntry)!, out var dependents) ? dependents : Enumerable.Empty(); } @@ -143,7 +148,7 @@ public virtual IEnumerable GetDependents(IUpdateEntry principalEnt /// public virtual IEnumerable GetDependentsUsingRelationshipSnapshot(IUpdateEntry principalEntry) { - return _map.TryGetValue(_principalKeyValueFactory.CreateFromRelationshipSnapshot(principalEntry), out var dependents) + return _map.TryGetValue(_principalKeyValueFactory.CreateFromRelationshipSnapshot(principalEntry)!, out var dependents) ? dependents : Enumerable.Empty(); } diff --git a/src/EFCore/ChangeTracking/Internal/EmptyShadowValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/EmptyShadowValuesFactoryFactory.cs index f2161dbcbbf..e1a34a40505 100644 --- a/src/EFCore/ChangeTracking/Internal/EmptyShadowValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/EmptyShadowValuesFactoryFactory.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -39,7 +41,7 @@ protected override int GetPropertyCount(IEntityType entityType) /// 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 override ValueComparer GetValueComparer(IProperty property) + protected override ValueComparer? GetValueComparer(IProperty property) => null; /// diff --git a/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs b/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs index 06bc8e0a424..cc2000e535c 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityEntryGraphIterator.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs index d7d5d9b16d1..ee175b59360 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityGraphAttacher.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs b/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs index ef743d3716e..3168adcebfb 100644 --- a/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs +++ b/src/EFCore/ChangeTracking/Internal/EntityReferenceMap.cs @@ -10,6 +10,10 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -21,12 +25,12 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal public class EntityReferenceMap { private readonly bool _hasSubMap; - private Dictionary _detachedReferenceMap; - private Dictionary _unchangedReferenceMap; - private Dictionary _addedReferenceMap; - private Dictionary _modifiedReferenceMap; - private Dictionary _deletedReferenceMap; - private Dictionary _sharedTypeReferenceMap; + private Dictionary? _detachedReferenceMap; + private Dictionary? _unchangedReferenceMap; + private Dictionary? _addedReferenceMap; + private Dictionary? _modifiedReferenceMap; + private Dictionary? _deletedReferenceMap; + private Dictionary? _sharedTypeReferenceMap; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -115,8 +119,8 @@ public virtual void Update( /// public virtual bool TryGet( [NotNull] object entity, - [CanBeNull] IEntityType entityType, - [CanBeNull] out InternalEntityEntry entry, + [CanBeNull] IEntityType? entityType, + [CanBeNull] [CA.NotNullWhen(true)] out InternalEntityEntry? entry, bool throwOnNonUniqueness) { entry = null; @@ -269,22 +273,22 @@ var numberOfStates { if (returnUnchanged) { - return _unchangedReferenceMap.Values; + return _unchangedReferenceMap!.Values; } if (returnAdded) { - return _addedReferenceMap.Values; + return _addedReferenceMap!.Values; } if (returnModified) { - return _modifiedReferenceMap.Values; + return _modifiedReferenceMap!.Values; } if (returnDeleted) { - return _deletedReferenceMap.Values; + return _deletedReferenceMap!.Values; } } @@ -313,7 +317,7 @@ private IEnumerable GetEntriesForState( { if (returnAdded) { - foreach (var entry in _addedReferenceMap.Values) + foreach (var entry in _addedReferenceMap!.Values) { yield return entry; } @@ -321,7 +325,7 @@ private IEnumerable GetEntriesForState( if (returnModified) { - foreach (var entry in _modifiedReferenceMap.Values) + foreach (var entry in _modifiedReferenceMap!.Values) { yield return entry; } @@ -329,7 +333,7 @@ private IEnumerable GetEntriesForState( if (returnDeleted) { - foreach (var entry in _deletedReferenceMap.Values) + foreach (var entry in _deletedReferenceMap!.Values) { yield return entry; } @@ -337,7 +341,7 @@ private IEnumerable GetEntriesForState( if (returnUnchanged) { - foreach (var entry in _unchangedReferenceMap.Values) + foreach (var entry in _unchangedReferenceMap!.Values) { yield return entry; } @@ -345,7 +349,7 @@ private IEnumerable GetEntriesForState( if (hasSharedTypes) { - foreach (var subMap in _sharedTypeReferenceMap.Values) + foreach (var subMap in _sharedTypeReferenceMap!.Values) { foreach (var entry in subMap.GetEntriesForState(added, modified, deleted, unchanged)) { @@ -377,16 +381,16 @@ private void Remove( _detachedReferenceMap?.Remove(entity); break; case EntityState.Unchanged: - _unchangedReferenceMap.Remove(entity); + _unchangedReferenceMap?.Remove(entity); break; case EntityState.Deleted: - _deletedReferenceMap.Remove(entity); + _deletedReferenceMap?.Remove(entity); break; case EntityState.Modified: - _modifiedReferenceMap.Remove(entity); + _modifiedReferenceMap?.Remove(entity); break; case EntityState.Added: - _addedReferenceMap.Remove(entity); + _addedReferenceMap?.Remove(entity); break; } } diff --git a/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs index 188e086ac25..06b948fe826 100644 --- a/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/EntryCurrentProviderValueComparer.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -38,7 +40,7 @@ public EntryCurrentProviderValueComparer( /// 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 override object GetPropertyValue(IUpdateEntry entry) + protected override object? GetPropertyValue(IUpdateEntry entry) => _converter.ConvertToProvider(base.GetPropertyValue(entry)); } } diff --git a/src/EFCore/ChangeTracking/Internal/EntryCurrentValueComparer.cs b/src/EFCore/ChangeTracking/Internal/EntryCurrentValueComparer.cs index a5d2d5b5940..dbaf9e1bfcb 100644 --- a/src/EFCore/ChangeTracking/Internal/EntryCurrentValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/EntryCurrentValueComparer.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -49,7 +51,7 @@ public EntryCurrentValueComparer([NotNull] IPropertyBase property, [NotNull] ICo /// 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 object GetPropertyValue([NotNull] IUpdateEntry entry) + protected virtual object? GetPropertyValue([NotNull] IUpdateEntry entry) => entry.GetCurrentValue(_property); /// @@ -58,8 +60,25 @@ protected virtual object GetPropertyValue([NotNull] IUpdateEntry entry) /// 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 int Compare(IUpdateEntry x, IUpdateEntry y) - => ComparePropertyValues(x.GetCurrentValue(_property), y.GetCurrentValue(_property)); + public virtual int Compare(IUpdateEntry? x, IUpdateEntry? y) + { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + + return ComparePropertyValues(x.GetCurrentValue(_property), y.GetCurrentValue(_property)); + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -67,7 +86,7 @@ public virtual int Compare(IUpdateEntry x, IUpdateEntry y) /// 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 int ComparePropertyValues([CanBeNull] object x, [CanBeNull] object y) + protected virtual int ComparePropertyValues([CanBeNull] object? x, [CanBeNull] object? y) => _underlyingComparer.Compare(x, y); /// @@ -76,7 +95,7 @@ protected virtual int ComparePropertyValues([CanBeNull] object x, [CanBeNull] ob /// 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 bool Equals(IUpdateEntry x, IUpdateEntry y) + public virtual bool Equals(IUpdateEntry? x, IUpdateEntry? y) => Compare(x, y) == 0; /// diff --git a/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs index 7d0515ef623..91a67838266 100644 --- a/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/EntryPropertyValues.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -21,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// public abstract class EntryPropertyValues : PropertyValues { - private IReadOnlyList _properties; + private IReadOnlyList? _properties; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -81,7 +83,7 @@ public override void SetValues(object obj) /// public override PropertyValues Clone() { - var values = new object[Properties.Count]; + var values = new object?[Properties.Count]; for (var i = 0; i < values.Length; i++) { values[i] = GetValueInternal(Properties[i]); @@ -114,7 +116,7 @@ public override void SetValues(PropertyValues propertyValues) /// public override IReadOnlyList Properties { - [DebuggerStepThrough] get => _properties ?? (_properties = EntityType.GetProperties().ToList()); + [DebuggerStepThrough] get => _properties ??= EntityType.GetProperties().ToList(); } /// @@ -123,7 +125,7 @@ public override IReadOnlyList Properties /// 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 override object this[string propertyName] + public override object? this[string propertyName] { get => GetValueInternal(EntityType.GetProperty(propertyName)); set => SetValueInternal(EntityType.GetProperty(propertyName), value); @@ -135,7 +137,7 @@ public override object this[string propertyName] /// 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 override object this[IProperty property] + public override object? this[IProperty property] { get => GetValueInternal(EntityType.CheckPropertyBelongsToType(property)); set => SetValueInternal(EntityType.CheckPropertyBelongsToType(property), value); @@ -147,7 +149,7 @@ public override object this[IProperty property] /// 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 abstract void SetValueInternal([NotNull] IProperty property, [CanBeNull] object value); + protected abstract void SetValueInternal([NotNull] IProperty property, [CanBeNull] object? value); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -155,6 +157,6 @@ public override object this[IProperty property] /// 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 abstract object GetValueInternal([NotNull] IProperty property); + protected abstract object? GetValueInternal([NotNull] IProperty property); } } diff --git a/src/EFCore/ChangeTracking/Internal/IChangeDetector.cs b/src/EFCore/ChangeTracking/Internal/IChangeDetector.cs index 7bd36c02a65..f07eef5b0ee 100644 --- a/src/EFCore/ChangeTracking/Internal/IChangeDetector.cs +++ b/src/EFCore/ChangeTracking/Internal/IChangeDetector.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/IChangeTrackerFactory.cs b/src/EFCore/ChangeTracking/Internal/IChangeTrackerFactory.cs index 62d72994f69..44cfe9777fe 100644 --- a/src/EFCore/ChangeTracking/Internal/IChangeTrackerFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/IChangeTrackerFactory.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/IDependentsMap.cs b/src/EFCore/ChangeTracking/Internal/IDependentsMap.cs index 7048f0aa99d..333ea643ddb 100644 --- a/src/EFCore/ChangeTracking/Internal/IDependentsMap.cs +++ b/src/EFCore/ChangeTracking/Internal/IDependentsMap.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/IEntityGraphAttacher.cs b/src/EFCore/ChangeTracking/Internal/IEntityGraphAttacher.cs index df5a8efd6ee..426ccdd9747 100644 --- a/src/EFCore/ChangeTracking/Internal/IEntityGraphAttacher.cs +++ b/src/EFCore/ChangeTracking/Internal/IEntityGraphAttacher.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/IIdentityMap.cs b/src/EFCore/ChangeTracking/Internal/IIdentityMap.cs index bf3a7862e6f..c7b81f7a9c0 100644 --- a/src/EFCore/ChangeTracking/Internal/IIdentityMap.cs +++ b/src/EFCore/ChangeTracking/Internal/IIdentityMap.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -45,7 +47,7 @@ public interface IIdentityMap /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] object[] keyValues); + InternalEntityEntry? TryGetEntry([NotNull] object?[] keyValues); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -53,7 +55,7 @@ public interface IIdentityMap /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] object[] keyValues, bool throwOnNullKey, out bool hasNullKey); + InternalEntityEntry? TryGetEntry([NotNull] object?[] keyValues, bool throwOnNullKey, out bool hasNullKey); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -61,7 +63,7 @@ public interface IIdentityMap /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] IForeignKey foreignKey, [NotNull] InternalEntityEntry dependentEntry); + InternalEntityEntry? TryGetEntry([NotNull] IForeignKey foreignKey, [NotNull] InternalEntityEntry dependentEntry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -69,7 +71,7 @@ public interface IIdentityMap /// 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. /// - InternalEntityEntry TryGetEntryUsingPreStoreGeneratedValues( + InternalEntityEntry? TryGetEntryUsingPreStoreGeneratedValues( [NotNull] IForeignKey foreignKey, [NotNull] InternalEntityEntry dependentEntry); @@ -79,7 +81,7 @@ InternalEntityEntry TryGetEntryUsingPreStoreGeneratedValues( /// 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. /// - InternalEntityEntry TryGetEntryUsingRelationshipSnapshot( + InternalEntityEntry? TryGetEntryUsingRelationshipSnapshot( [NotNull] IForeignKey foreignKey, [NotNull] InternalEntityEntry dependentEntry); @@ -137,7 +139,7 @@ InternalEntityEntry TryGetEntryUsingRelationshipSnapshot( /// 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. /// - IDependentsMap FindDependentsMap([NotNull] IForeignKey foreignKey); + IDependentsMap? FindDependentsMap([NotNull] IForeignKey foreignKey); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryFactory.cs b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryFactory.cs index 6c9c76833cf..05d72f99bd0 100644 --- a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryFactory.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -32,7 +34,7 @@ public interface IInternalEntityEntryFactory InternalEntityEntry Create( [NotNull] IStateManager stateManager, [NotNull] IEntityType entityType, - [CanBeNull] object entity); + [NotNull] object entity); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -43,7 +45,7 @@ InternalEntityEntry Create( InternalEntityEntry Create( [NotNull] IStateManager stateManager, [NotNull] IEntityType entityType, - [CanBeNull] object entity, + [NotNull] object entity, in ValueBuffer valueBuffer); } } diff --git a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryNotifier.cs b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryNotifier.cs index 10195eda738..ddd0802251f 100644 --- a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryNotifier.cs +++ b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntryNotifier.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -57,8 +59,8 @@ public interface IInternalEntityEntryNotifier void NavigationReferenceChanged( [NotNull] InternalEntityEntry entry, [NotNull] INavigation navigation, - [CanBeNull] object oldValue, - [CanBeNull] object newValue); + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -83,8 +85,8 @@ void KeyPropertyChanged( [NotNull] IProperty property, [NotNull] IEnumerable keys, [NotNull] IEnumerable foreignKeys, - [CanBeNull] object oldValue, - [CanBeNull] object newValue); + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntrySubscriber.cs b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntrySubscriber.cs index a5a7b7231a0..e0cb8679f00 100644 --- a/src/EFCore/ChangeTracking/Internal/IInternalEntityEntrySubscriber.cs +++ b/src/EFCore/ChangeTracking/Internal/IInternalEntityEntrySubscriber.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/IKeyPropagator.cs b/src/EFCore/ChangeTracking/Internal/IKeyPropagator.cs index b35787e87a8..b08fb5606b3 100644 --- a/src/EFCore/ChangeTracking/Internal/IKeyPropagator.cs +++ b/src/EFCore/ChangeTracking/Internal/IKeyPropagator.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -31,7 +33,7 @@ public interface IKeyPropagator /// 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. /// - InternalEntityEntry PropagateValue([NotNull] InternalEntityEntry entry, [NotNull] IProperty property); + InternalEntityEntry? PropagateValue([NotNull] InternalEntityEntry entry, [NotNull] IProperty property); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -39,7 +41,7 @@ public interface IKeyPropagator /// 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. /// - Task PropagateValueAsync( + Task PropagateValueAsync( [NotNull] InternalEntityEntry entry, [NotNull] IProperty property, CancellationToken cancellationToken = default); diff --git a/src/EFCore/ChangeTracking/Internal/ILocalViewListener.cs b/src/EFCore/ChangeTracking/Internal/ILocalViewListener.cs index 7371ef54c62..5161ce45e13 100644 --- a/src/EFCore/ChangeTracking/Internal/ILocalViewListener.cs +++ b/src/EFCore/ChangeTracking/Internal/ILocalViewListener.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/INavigationFixer.cs b/src/EFCore/ChangeTracking/Internal/INavigationFixer.cs index 5dfacd64b63..57ebf18a277 100644 --- a/src/EFCore/ChangeTracking/Internal/INavigationFixer.cs +++ b/src/EFCore/ChangeTracking/Internal/INavigationFixer.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -33,8 +35,8 @@ public interface INavigationFixer void NavigationReferenceChanged( [NotNull] InternalEntityEntry entry, [NotNull] INavigationBase navigationBase, - [CanBeNull] object oldValue, - [CanBeNull] object newValue); + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -67,8 +69,8 @@ void KeyPropertyChanged( [NotNull] IProperty property, [NotNull] IEnumerable containingPrincipalKeys, [NotNull] IEnumerable containingForeignKeys, - [CanBeNull] object oldValue, - [CanBeNull] object newValue); + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/ISnapshot.cs b/src/EFCore/ChangeTracking/Internal/ISnapshot.cs index 45d8251efde..dfdf83f7d8d 100644 --- a/src/EFCore/ChangeTracking/Internal/ISnapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/ISnapshot.cs @@ -3,6 +3,8 @@ using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -19,7 +21,7 @@ public interface ISnapshot /// 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. /// - object this[int index] { get; [param: CanBeNull] set; } + object? this[int index] { get; [param: CanBeNull] set; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,6 +29,6 @@ public interface ISnapshot /// 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. /// - T GetValue(int index); + T? GetValue(int index); } } diff --git a/src/EFCore/ChangeTracking/Internal/IStateManager.cs b/src/EFCore/ChangeTracking/Internal/IStateManager.cs index 01f61126867..77c2c9a2d68 100644 --- a/src/EFCore/ChangeTracking/Internal/IStateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/IStateManager.cs @@ -15,6 +15,8 @@ using Microsoft.EntityFrameworkCore.Update; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -79,7 +81,7 @@ public interface IStateManager : IResettableService /// 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. /// - InternalEntityEntry GetOrCreateEntry([NotNull] object entity, [CanBeNull] IEntityType entityType); + InternalEntityEntry GetOrCreateEntry([NotNull] object entity, [CanBeNull] IEntityType? entityType); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -106,7 +108,7 @@ InternalEntityEntry StartTrackingFromQuery( /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] IKey key, [NotNull] object[] keyValues); + InternalEntityEntry? TryGetEntry([NotNull] IKey key, [NotNull] object?[] keyValues); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -114,7 +116,7 @@ InternalEntityEntry StartTrackingFromQuery( /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] IKey key, [NotNull] object[] keyValues, bool throwOnNullKey, out bool hasNullKey); + InternalEntityEntry? TryGetEntry([NotNull] IKey key, [NotNull] object?[] keyValues, bool throwOnNullKey, out bool hasNullKey); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -122,7 +124,7 @@ InternalEntityEntry StartTrackingFromQuery( /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] object entity, bool throwOnNonUniqueness = true); + InternalEntityEntry? TryGetEntry([NotNull] object entity, bool throwOnNonUniqueness = true); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -130,7 +132,7 @@ InternalEntityEntry StartTrackingFromQuery( /// 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. /// - InternalEntityEntry TryGetEntry([NotNull] object entity, [NotNull] IEntityType type, bool throwOnTypeMismatch = true); + InternalEntityEntry? TryGetEntry([NotNull] object entity, [NotNull] IEntityType type, bool throwOnTypeMismatch = true); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -278,7 +280,7 @@ void RecordReferencedUntrackedEntity( /// 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. /// - InternalEntityEntry FindPrincipal([NotNull] InternalEntityEntry dependentEntry, [NotNull] IForeignKey foreignKey); + InternalEntityEntry? FindPrincipal([NotNull] InternalEntityEntry dependentEntry, [NotNull] IForeignKey foreignKey); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -286,7 +288,7 @@ void RecordReferencedUntrackedEntity( /// 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. /// - InternalEntityEntry FindPrincipalUsingPreStoreGeneratedValues( + InternalEntityEntry? FindPrincipalUsingPreStoreGeneratedValues( [NotNull] InternalEntityEntry dependentEntry, [NotNull] IForeignKey foreignKey); @@ -296,7 +298,7 @@ InternalEntityEntry FindPrincipalUsingPreStoreGeneratedValues( /// 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. /// - InternalEntityEntry FindPrincipalUsingRelationshipSnapshot( + InternalEntityEntry? FindPrincipalUsingRelationshipSnapshot( [NotNull] InternalEntityEntry dependentEntry, [NotNull] IForeignKey foreignKey); @@ -322,7 +324,7 @@ InternalEntityEntry FindPrincipalUsingRelationshipSnapshot( /// 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. /// - IEnumerable GetDependentsFromNavigation( + IEnumerable? GetDependentsFromNavigation( [NotNull] IUpdateEntry principalEntry, [NotNull] IForeignKey foreignKey); @@ -398,7 +400,7 @@ IEnumerable GetDependentsUsingRelationshipSnapshot( /// 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. /// - event EventHandler Tracked; + event EventHandler? Tracked; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -414,7 +416,7 @@ IEnumerable GetDependentsUsingRelationshipSnapshot( /// 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. /// - event EventHandler StateChanged; + event EventHandler? StateChanged; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -446,7 +448,7 @@ IEnumerable GetDependentsUsingRelationshipSnapshot( /// 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. /// - void CascadeDelete([NotNull] InternalEntityEntry entry, bool force, [CanBeNull] IEnumerable foreignKeys = null); + void CascadeDelete([NotNull] InternalEntityEntry entry, bool force, [CanBeNull] IEnumerable? foreignKeys = null); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/IValueGenerationManager.cs b/src/EFCore/ChangeTracking/Internal/IValueGenerationManager.cs index 2526b5dcb51..07e63c653b8 100644 --- a/src/EFCore/ChangeTracking/Internal/IValueGenerationManager.cs +++ b/src/EFCore/ChangeTracking/Internal/IValueGenerationManager.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -39,7 +41,7 @@ public interface IValueGenerationManager /// 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. /// - InternalEntityEntry Propagate([NotNull] InternalEntityEntry entry); + InternalEntityEntry? Propagate([NotNull] InternalEntityEntry entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs index 67beda7fb9c..0d3c6534093 100644 --- a/src/EFCore/ChangeTracking/Internal/IdentityMap.cs +++ b/src/EFCore/ChangeTracking/Internal/IdentityMap.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -21,11 +23,12 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class IdentityMap : IIdentityMap + where TKey : notnull { private readonly bool _sensitiveLoggingEnabled; private readonly Dictionary _identityMap; - private readonly IForeignKey[] _foreignKeys; - private Dictionary _dependentMaps; + private readonly IForeignKey[]? _foreignKeys; + private Dictionary? _dependentMaps; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -87,7 +90,7 @@ public virtual bool Contains(in ValueBuffer valueBuffer) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual bool Contains(IForeignKey foreignKey, in ValueBuffer valueBuffer) - => foreignKey.GetDependentKeyValueFactory().TryCreateFromBuffer(valueBuffer, out var key) + => foreignKey.GetDependentKeyValueFactory()!.TryCreateFromBuffer(valueBuffer, out var key) && _identityMap.ContainsKey(key); /// @@ -96,7 +99,7 @@ public virtual bool Contains(IForeignKey foreignKey, in ValueBuffer valueBuffer) /// 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 InternalEntityEntry TryGetEntry(object[] keyValues) + public virtual InternalEntityEntry? TryGetEntry(object?[] keyValues) { var key = PrincipalKeyValueFactory.CreateFromKeyValues(keyValues); return key != null && _identityMap.TryGetValue((TKey)key, out var entry) ? entry : null; @@ -108,7 +111,7 @@ public virtual InternalEntityEntry TryGetEntry(object[] keyValues) /// 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 InternalEntityEntry TryGetEntry(object[] keyValues, bool throwOnNullKey, out bool hasNullKey) + public virtual InternalEntityEntry? TryGetEntry(object?[] keyValues, bool throwOnNullKey, out bool hasNullKey) { var key = PrincipalKeyValueFactory.CreateFromKeyValues(keyValues); @@ -121,13 +124,13 @@ public virtual InternalEntityEntry TryGetEntry(object[] keyValues, bool throwOnN throw new InvalidOperationException( CoreStrings.InvalidKeyValue( Key.DeclaringEntityType.DisplayName(), - PrincipalKeyValueFactory.FindNullPropertyInKeyValues(keyValues).Name)); + PrincipalKeyValueFactory.FindNullPropertyInKeyValues(keyValues)!.Name)); } throw new InvalidOperationException( CoreStrings.InvalidAlternateKeyValue( Key.DeclaringEntityType.DisplayName(), - PrincipalKeyValueFactory.FindNullPropertyInKeyValues(keyValues).Name)); + PrincipalKeyValueFactory.FindNullPropertyInKeyValues(keyValues)!.Name)); } hasNullKey = true; @@ -162,8 +165,8 @@ public virtual InternalEntityEntry TryGetEntry(object[] keyValues, bool throwOnN /// 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 InternalEntityEntry TryGetEntry(IForeignKey foreignKey, InternalEntityEntry dependentEntry) - => foreignKey.GetDependentKeyValueFactory().TryCreateFromCurrentValues(dependentEntry, out var key) + public virtual InternalEntityEntry? TryGetEntry(IForeignKey foreignKey, InternalEntityEntry dependentEntry) + => foreignKey.GetDependentKeyValueFactory()!.TryCreateFromCurrentValues(dependentEntry, out var key) && _identityMap.TryGetValue(key, out var entry) ? entry : null; @@ -174,10 +177,10 @@ public virtual InternalEntityEntry TryGetEntry(IForeignKey foreignKey, InternalE /// 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 InternalEntityEntry TryGetEntryUsingPreStoreGeneratedValues( + public virtual InternalEntityEntry? TryGetEntryUsingPreStoreGeneratedValues( IForeignKey foreignKey, InternalEntityEntry dependentEntry) - => foreignKey.GetDependentKeyValueFactory().TryCreateFromPreStoreGeneratedCurrentValues(dependentEntry, out var key) + => foreignKey.GetDependentKeyValueFactory()!.TryCreateFromPreStoreGeneratedCurrentValues(dependentEntry, out var key) && _identityMap.TryGetValue(key, out var entry) ? entry : null; @@ -188,8 +191,8 @@ public virtual InternalEntityEntry TryGetEntryUsingPreStoreGeneratedValues( /// 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 InternalEntityEntry TryGetEntryUsingRelationshipSnapshot(IForeignKey foreignKey, InternalEntityEntry dependentEntry) - => foreignKey.GetDependentKeyValueFactory().TryCreateFromRelationshipSnapshot(dependentEntry, out var key) + public virtual InternalEntityEntry? TryGetEntryUsingRelationshipSnapshot(IForeignKey foreignKey, InternalEntityEntry dependentEntry) + => foreignKey.GetDependentKeyValueFactory()!.TryCreateFromRelationshipSnapshot(dependentEntry, out var key) && _identityMap.TryGetValue(key, out var entry) ? entry : null; @@ -201,7 +204,7 @@ public virtual InternalEntityEntry TryGetEntryUsingRelationshipSnapshot(IForeign /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void AddOrUpdate(InternalEntityEntry entry) - => Add(PrincipalKeyValueFactory.CreateFromCurrentValues(entry), entry, updateDuplicate: true); + => Add(PrincipalKeyValueFactory.CreateFromCurrentValues(entry)!, entry, updateDuplicate: true); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -210,7 +213,7 @@ public virtual void AddOrUpdate(InternalEntityEntry entry) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void Add(InternalEntityEntry entry) - => Add(PrincipalKeyValueFactory.CreateFromCurrentValues(entry), entry); + => Add(PrincipalKeyValueFactory.CreateFromCurrentValues(entry)!, entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -219,7 +222,7 @@ public virtual void Add(InternalEntityEntry entry) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void Add(object[] keyValues, InternalEntityEntry entry) - => Add((TKey)PrincipalKeyValueFactory.CreateFromKeyValues(keyValues), entry); + => Add((TKey)PrincipalKeyValueFactory.CreateFromKeyValues(keyValues)!, entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -356,7 +359,7 @@ public virtual IDependentsMap GetDependentsMap(IForeignKey foreignKey) /// 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 IDependentsMap FindDependentsMap(IForeignKey foreignKey) + public virtual IDependentsMap? FindDependentsMap(IForeignKey foreignKey) => _dependentMaps != null && _dependentMaps.TryGetValue(foreignKey, out var map) ? map @@ -381,7 +384,7 @@ public virtual void Clear() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void Remove(InternalEntityEntry entry) - => Remove(PrincipalKeyValueFactory.CreateFromCurrentValues(entry), entry); + => Remove(PrincipalKeyValueFactory.CreateFromCurrentValues(entry)!, entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -390,7 +393,7 @@ public virtual void Remove(InternalEntityEntry entry) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void RemoveUsingRelationshipSnapshot(InternalEntityEntry entry) - => Remove(PrincipalKeyValueFactory.CreateFromRelationshipSnapshot(entry), entry); + => Remove(PrincipalKeyValueFactory.CreateFromRelationshipSnapshot(entry)!, entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -400,7 +403,7 @@ public virtual void RemoveUsingRelationshipSnapshot(InternalEntityEntry entry) /// protected virtual void Remove([NotNull] TKey key, [NotNull] InternalEntityEntry entry) { - InternalEntityEntry otherEntry = null; + InternalEntityEntry? otherEntry = null; if (entry.SharedIdentityEntry != null) { otherEntry = entry.SharedIdentityEntry; diff --git a/src/EFCore/ChangeTracking/Internal/IdentityMapFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/IdentityMapFactoryFactory.cs index d50247cf00d..5c7ff92d776 100644 --- a/src/EFCore/ChangeTracking/Internal/IdentityMapFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/IdentityMapFactoryFactory.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -24,12 +26,13 @@ public class IdentityMapFactoryFactory /// public virtual Func Create([NotNull] IKey key) => (Func)typeof(IdentityMapFactoryFactory).GetTypeInfo() - .GetDeclaredMethod(nameof(CreateFactory)) + .GetRequiredDeclaredMethod(nameof(CreateFactory)) .MakeGenericMethod(key.GetKeyType()) - .Invoke(null, new object[] { key }); + .Invoke(null, new object[] { key })!; [UsedImplicitly] private static Func CreateFactory(IKey key) + where TKey : notnull { var factory = key.GetPrincipalKeyValueFactory(); diff --git a/src/EFCore/ChangeTracking/Internal/InternalClrEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalClrEntityEntry.cs index 4dbe1d63cb1..cc3cce26f7e 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalClrEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalClrEntityEntry.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs index 30872cee948..7a7969f38df 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs @@ -20,6 +20,8 @@ using Microsoft.EntityFrameworkCore.Update; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -66,7 +68,7 @@ protected InternalEntityEntry( /// 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. /// - void IUpdateEntry.SetOriginalValue(IProperty property, object value) + void IUpdateEntry.SetOriginalValue(IProperty property, object? value) => SetOriginalValue(property, value); /// @@ -112,7 +114,7 @@ EntityState IUpdateEntry.EntityState /// 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 InternalEntityEntry SharedIdentityEntry { get; [param: CanBeNull] set; } + public virtual InternalEntityEntry? SharedIdentityEntry { get; [param: CanBeNull] set; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -554,7 +556,7 @@ public virtual bool HasTemporaryValue(IProperty property) private CurrentValueType GetValueType( IProperty property, - Func equals = null) + Func? equals = null) { var tempIndex = property.GetStoreGeneratedIndex(); if (tempIndex == -1) @@ -600,7 +602,7 @@ private CurrentValueType GetValueType( /// 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 void SetTemporaryValue([NotNull] IProperty property, [CanBeNull] object value, bool setModified = true) + public virtual void SetTemporaryValue([NotNull] IProperty property, [CanBeNull] object? value, bool setModified = true) { if (property.GetStoreGeneratedIndex() == -1) { @@ -617,7 +619,7 @@ public virtual void SetTemporaryValue([NotNull] IProperty property, [CanBeNull] /// 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 void SetStoreGeneratedValue(IProperty property, object value) + public virtual void SetStoreGeneratedValue(IProperty property, object? value) { if (property.GetStoreGeneratedIndex() == -1) { @@ -661,7 +663,7 @@ public virtual void MarkUnknown([NotNull] IProperty property) => _stateData.FlagProperty(property.GetIndex(), PropertyFlag.Unknown, true); internal static readonly MethodInfo ReadShadowValueMethod - = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethod(nameof(ReadShadowValue)); + = typeof(InternalEntityEntry).GetTypeInfo().GetRequiredDeclaredMethod(nameof(ReadShadowValue)); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -670,35 +672,35 @@ internal static readonly MethodInfo ReadShadowValueMethod /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [UsedImplicitly] - protected virtual T ReadShadowValue(int shadowIndex) + protected virtual T? ReadShadowValue(int shadowIndex) => default; internal static readonly MethodInfo ReadOriginalValueMethod - = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethod(nameof(ReadOriginalValue)); + = typeof(InternalEntityEntry).GetTypeInfo().GetRequiredDeclaredMethod(nameof(ReadOriginalValue)); [UsedImplicitly] - private T ReadOriginalValue(IProperty property, int originalValueIndex) + private T? ReadOriginalValue(IProperty property, int originalValueIndex) => _originalValues.GetValue(this, property, originalValueIndex); internal static readonly MethodInfo ReadRelationshipSnapshotValueMethod - = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethod(nameof(ReadRelationshipSnapshotValue)); + = typeof(InternalEntityEntry).GetTypeInfo().GetRequiredDeclaredMethod(nameof(ReadRelationshipSnapshotValue)); [UsedImplicitly] - private T ReadRelationshipSnapshotValue(IPropertyBase propertyBase, int relationshipSnapshotIndex) + private T? ReadRelationshipSnapshotValue(IPropertyBase propertyBase, int relationshipSnapshotIndex) => _relationshipsSnapshot.GetValue(this, propertyBase, relationshipSnapshotIndex); internal static readonly MethodInfo ReadStoreGeneratedValueMethod - = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethod(nameof(ReadStoreGeneratedValue)); + = typeof(InternalEntityEntry).GetTypeInfo().GetRequiredDeclaredMethod(nameof(ReadStoreGeneratedValue)); [UsedImplicitly] - private T ReadStoreGeneratedValue(int storeGeneratedIndex) + private T? ReadStoreGeneratedValue(int storeGeneratedIndex) => _storeGeneratedValues.GetValue(storeGeneratedIndex); internal static readonly MethodInfo ReadTemporaryValueMethod - = typeof(InternalEntityEntry).GetTypeInfo().GetDeclaredMethod(nameof(ReadTemporaryValue)); + = typeof(InternalEntityEntry).GetTypeInfo().GetRequiredDeclaredMethod(nameof(ReadTemporaryValue)); [UsedImplicitly] - private T ReadTemporaryValue(int storeGeneratedIndex) + private T? ReadTemporaryValue(int storeGeneratedIndex) => _temporaryValues.GetValue(storeGeneratedIndex); internal static readonly MethodInfo GetCurrentValueMethod @@ -711,8 +713,8 @@ internal static readonly MethodInfo GetCurrentValueMethod /// 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 TProperty GetCurrentValue(IPropertyBase propertyBase) - => ((Func)propertyBase.GetPropertyAccessors().CurrentValueGetter)(this); + public virtual TProperty? GetCurrentValue(IPropertyBase propertyBase) + => ((Func)propertyBase.GetPropertyAccessors().CurrentValueGetter)(this); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -720,8 +722,8 @@ public virtual TProperty GetCurrentValue(IPropertyBase propertyBase) /// 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 TProperty GetOriginalValue(IProperty property) - => ((Func)property.GetPropertyAccessors().OriginalValueGetter)(this); + public virtual TProperty? GetOriginalValue(IProperty property) + => ((Func)property.GetPropertyAccessors().OriginalValueGetter!)(this); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -729,8 +731,8 @@ public virtual TProperty GetOriginalValue(IProperty property) /// 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 TProperty GetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase) - => ((Func)propertyBase.GetPropertyAccessors().RelationshipSnapshotGetter)( + public virtual TProperty? GetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase) + => ((Func)propertyBase.GetPropertyAccessors().RelationshipSnapshotGetter)( this); /// @@ -739,7 +741,7 @@ public virtual TProperty GetRelationshipSnapshotValue([NotNull] IProp /// 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 object ReadPropertyValue([NotNull] IPropertyBase propertyBase) + protected virtual object? ReadPropertyValue([NotNull] IPropertyBase propertyBase) { Check.DebugAssert(!propertyBase.IsShadowProperty(), "propertyBase is shadow property"); @@ -767,7 +769,7 @@ protected virtual bool PropertyHasDefaultValue([NotNull] IPropertyBase propertyB /// protected virtual void WritePropertyValue( [NotNull] IPropertyBase propertyBase, - [CanBeNull] object value, + [CanBeNull] object? value, bool forMaterialization) { Check.DebugAssert(!propertyBase.IsShadowProperty(), "propertyBase is shadow property"); @@ -791,7 +793,7 @@ public virtual object GetOrCreateCollection([NotNull] INavigationBase navigation { Check.DebugAssert(!navigationBase.IsShadowProperty(), "navigation is shadow property"); - return navigationBase.GetCollectionAccessor().GetOrCreate(Entity, forMaterialization); + return navigationBase.GetCollectionAccessor()!.GetOrCreate(Entity, forMaterialization); } /// @@ -804,7 +806,7 @@ public virtual bool CollectionContains([NotNull] INavigationBase navigationBase, { Check.DebugAssert(!navigationBase.IsShadowProperty(), "navigation is shadow property"); - return navigationBase.GetCollectionAccessor().Contains(Entity, value.Entity); + return navigationBase.GetCollectionAccessor()!.Contains(Entity, value.Entity); } /// @@ -820,7 +822,7 @@ public virtual bool AddToCollection( { Check.DebugAssert(!navigationBase.IsShadowProperty(), "navigation is shadow property"); - return navigationBase.GetCollectionAccessor().Add(Entity, value.Entity, forMaterialization); + return navigationBase.GetCollectionAccessor()!.Add(Entity, value.Entity, forMaterialization); } /// @@ -833,7 +835,7 @@ public virtual bool RemoveFromCollection([NotNull] INavigationBase navigationBas { Check.DebugAssert(!navigationBase.IsShadowProperty(), "navigation is shadow property"); - return navigationBase.GetCollectionAccessor().Remove(Entity, value.Entity); + return navigationBase.GetCollectionAccessor()!.Remove(Entity, value.Entity); } /// @@ -842,7 +844,7 @@ public virtual bool RemoveFromCollection([NotNull] INavigationBase navigationBas /// 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 object GetCurrentValue(IPropertyBase propertyBase) + public virtual object? GetCurrentValue(IPropertyBase propertyBase) => !(propertyBase is IProperty property) || !IsConceptualNull(property) ? this[propertyBase] : null; @@ -853,7 +855,7 @@ public virtual object GetCurrentValue(IPropertyBase propertyBase) /// 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 object GetPreStoreGeneratedCurrentValue(IPropertyBase propertyBase) + public virtual object? GetPreStoreGeneratedCurrentValue(IPropertyBase propertyBase) => !(propertyBase is IProperty property) || !IsConceptualNull(property) ? ReadPropertyValue(propertyBase) : null; @@ -864,7 +866,7 @@ public virtual object GetPreStoreGeneratedCurrentValue(IPropertyBase propertyBas /// 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 object GetOriginalValue(IPropertyBase propertyBase) + public virtual object? GetOriginalValue(IPropertyBase propertyBase) => _originalValues.GetValue(this, (IProperty)propertyBase); /// @@ -873,7 +875,7 @@ public virtual object GetOriginalValue(IPropertyBase propertyBase) /// 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 object GetRelationshipSnapshotValue(IPropertyBase propertyBase) + public virtual object? GetRelationshipSnapshotValue(IPropertyBase propertyBase) => _relationshipsSnapshot.GetValue(this, propertyBase); /// @@ -884,7 +886,7 @@ public virtual object GetRelationshipSnapshotValue(IPropertyBase propertyBase) /// public virtual void SetOriginalValue( [NotNull] IPropertyBase propertyBase, - [CanBeNull] object value, + [CanBeNull] object? value, int index = -1) { EnsureOriginalValues(); @@ -915,7 +917,7 @@ public virtual void SetOriginalValue( /// 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 void SetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase, [CanBeNull] object value) + public virtual void SetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase, [CanBeNull] object? value) { EnsureRelationshipSnapshot(); _relationshipsSnapshot.SetValue(propertyBase, value); @@ -1041,7 +1043,7 @@ public virtual void AddRangeToCollectionSnapshot( /// 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 object this[[NotNull] IPropertyBase propertyBase] // Intentionally non-virtual + public object? this[[NotNull] IPropertyBase propertyBase] // Intentionally non-virtual { get { @@ -1087,7 +1089,7 @@ public object this[[NotNull] IPropertyBase propertyBase] // Intentionally non-vi /// public virtual void SetProperty( [NotNull] IPropertyBase propertyBase, - [CanBeNull] object value, + [CanBeNull] object? value, bool isMaterialization, bool setModified = true, bool isCascadeDelete = false) @@ -1095,7 +1097,7 @@ public virtual void SetProperty( private void SetProperty( [NotNull] IPropertyBase propertyBase, - [CanBeNull] object value, + [CanBeNull] object? value, bool isMaterialization, bool setModified, bool isCascadeDelete, @@ -1106,7 +1108,7 @@ private void SetProperty( var asProperty = propertyBase as IProperty; int propertyIndex; CurrentValueType currentValueType; - Func equals; + Func equals; if (asProperty != null) { @@ -1184,7 +1186,7 @@ private void SetProperty( case CurrentValueType.StoreGenerated: if (!_storeGeneratedValues.IsEmpty) { - var defaultValue = asProperty.ClrType.GetDefaultValue(); + var defaultValue = asProperty!.ClrType.GetDefaultValue(); var storeGeneratedIndex = asProperty.GetStoreGeneratedIndex(); _storeGeneratedValues.SetValue(asProperty, defaultValue, storeGeneratedIndex); } @@ -1192,7 +1194,7 @@ private void SetProperty( case CurrentValueType.Temporary: if (!_temporaryValues.IsEmpty) { - var defaultValue = asProperty.ClrType.GetDefaultValue(); + var defaultValue = asProperty!.ClrType.GetDefaultValue(); var storeGeneratedIndex = asProperty.GetStoreGeneratedIndex(); _temporaryValues.SetValue(asProperty, defaultValue, storeGeneratedIndex); } @@ -1201,7 +1203,7 @@ private void SetProperty( } else { - var storeGeneratedIndex = asProperty.GetStoreGeneratedIndex(); + var storeGeneratedIndex = asProperty!.GetStoreGeneratedIndex(); Check.DebugAssert(storeGeneratedIndex >= 0, $"storeGeneratedIndex is {storeGeneratedIndex}"); if (valueType == CurrentValueType.StoreGenerated) @@ -1246,12 +1248,12 @@ private void SetProperty( } } - private static Func ValuesEqualFunc(IProperty property) + private static Func ValuesEqualFunc(IProperty property) { var comparer = property.GetValueComparer(); return comparer != null - ? (Func)((l, r) => comparer.Equals(l, r)) + ? (Func)((l, r) => comparer.Equals(l, r)) : (l, r) => Equals(l, r); } @@ -1549,7 +1551,7 @@ public virtual (bool IsGenerated, bool IsSet) IsKeySet get { var isGenerated = false; - var keyProperties = EntityType.FindPrimaryKey().Properties; + var keyProperties = EntityType.FindPrimaryKey()!.Properties; // ReSharper disable once ForCanBeConvertedToForeach // ReSharper disable once LoopCanBeConvertedToQuery @@ -1585,7 +1587,7 @@ public virtual bool IsKeyUnknown { get { - var keyProperties = EntityType.FindPrimaryKey().Properties; + var keyProperties = EntityType.FindPrimaryKey()!.Properties; // ReSharper disable once ForCanBeConvertedToForeach // ReSharper disable once LoopCanBeConvertedToQuery for (var i = 0; i < keyProperties.Count; i++) @@ -1617,7 +1619,7 @@ public virtual EntityEntry ToEntityEntry() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void HandleINotifyPropertyChanging( - [NotNull] object sender, + [NotNull] object? sender, [NotNull] PropertyChangingEventArgs eventArgs) { foreach (var propertyBase in GetNotificationProperties(EntityType, eventArgs.PropertyName)) @@ -1633,7 +1635,7 @@ public virtual void HandleINotifyPropertyChanging( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void HandleINotifyPropertyChanged( - [NotNull] object sender, + [NotNull] object? sender, [NotNull] PropertyChangedEventArgs eventArgs) { foreach (var propertyBase in GetNotificationProperties(EntityType, eventArgs.PropertyName)) @@ -1644,7 +1646,7 @@ public virtual void HandleINotifyPropertyChanged( private static IEnumerable GetNotificationProperties( [NotNull] IEntityType entityType, - [CanBeNull] string propertyName) + [CanBeNull] string? propertyName) { if (string.IsNullOrEmpty(propertyName)) { @@ -1669,7 +1671,7 @@ private static IEnumerable GetNotificationProperties( // ReSharper disable once AssignNullToNotNullAttribute var property = entityType.FindProperty(propertyName) ?? entityType.FindNavigation(propertyName) - ?? (IPropertyBase)entityType.FindSkipNavigation(propertyName); + ?? (IPropertyBase?)entityType.FindSkipNavigation(propertyName); if (property != null) { @@ -1685,7 +1687,7 @@ private static IEnumerable GetNotificationProperties( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void HandleINotifyCollectionChanged( - [NotNull] object sender, + [NotNull] object? sender, [NotNull] NotifyCollectionChangedEventArgs eventArgs) { var navigation = EntityType.GetNavigations() @@ -1700,7 +1702,7 @@ public virtual void HandleINotifyCollectionChanged( StateManager.InternalEntityEntryNotifier.NavigationCollectionChanged( this, navigation, - eventArgs.NewItems.OfType(), + eventArgs.NewItems!.OfType(), Enumerable.Empty()); break; case NotifyCollectionChangedAction.Remove: @@ -1708,14 +1710,14 @@ public virtual void HandleINotifyCollectionChanged( this, navigation, Enumerable.Empty(), - eventArgs.OldItems.OfType()); + eventArgs.OldItems!.OfType()); break; case NotifyCollectionChangedAction.Replace: StateManager.InternalEntityEntryNotifier.NavigationCollectionChanged( this, navigation, - eventArgs.NewItems.OfType(), - eventArgs.OldItems.OfType()); + eventArgs.NewItems!.OfType(), + eventArgs.OldItems!.OfType()); break; case NotifyCollectionChangedAction.Reset: throw new InvalidOperationException(CoreStrings.ResetNotSupported); @@ -1745,7 +1747,7 @@ public virtual void SetIsLoaded([NotNull] INavigationBase navigation, bool loade var lazyLoaderProperty = EntityType.GetServiceProperties().FirstOrDefault(p => p.ClrType == typeof(ILazyLoader)); if (lazyLoaderProperty != null) { - ((ILazyLoader)this[lazyLoaderProperty])?.SetLoaded(Entity, navigation.Name, loaded); + ((ILazyLoader?)this[lazyLoaderProperty])?.SetLoaded(Entity, navigation.Name, loaded); } } @@ -1778,7 +1780,7 @@ public virtual DebugView DebugView () => this.ToDebugString(ChangeTrackerDebugStringOptions.ShortDefault), () => this.ToDebugString(ChangeTrackerDebugStringOptions.LongDefault)); - IUpdateEntry IUpdateEntry.SharedIdentityEntry + IUpdateEntry? IUpdateEntry.SharedIdentityEntry => SharedIdentityEntry; private enum CurrentValueType diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntryFactory.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntryFactory.cs index e6aa3a3b6f5..2f35f235452 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntryFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntryNotifier.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntryNotifier.cs index 4c5a06813b6..d601358f161 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntryNotifier.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntryNotifier.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -24,9 +26,9 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// public class InternalEntityEntryNotifier : IInternalEntityEntryNotifier { - private readonly ILocalViewListener _localViewListener; - private readonly IChangeDetector _changeDetector; - private readonly INavigationFixer _navigationFixer; + private readonly ILocalViewListener? _localViewListener; + private readonly IChangeDetector? _changeDetector; + private readonly INavigationFixer? _navigationFixer; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,9 +37,9 @@ public class InternalEntityEntryNotifier : IInternalEntityEntryNotifier /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public InternalEntityEntryNotifier( - [CanBeNull] ILocalViewListener localViewListener, - [CanBeNull] IChangeDetector changeDetector, - [CanBeNull] INavigationFixer navigationFixer) + [CanBeNull] ILocalViewListener? localViewListener, + [CanBeNull] IChangeDetector? changeDetector, + [CanBeNull] INavigationFixer? navigationFixer) { _localViewListener = localViewListener; _changeDetector = changeDetector; @@ -52,8 +54,8 @@ public InternalEntityEntryNotifier( /// public virtual void StateChanging(InternalEntityEntry entry, EntityState newState) { - _navigationFixer.StateChanging(entry, newState); - _localViewListener.StateChanging(entry, newState); + _navigationFixer?.StateChanging(entry, newState); + _localViewListener?.StateChanging(entry, newState); } /// @@ -64,8 +66,8 @@ public virtual void StateChanging(InternalEntityEntry entry, EntityState newStat /// public virtual void StateChanged(InternalEntityEntry entry, EntityState oldState, bool fromQuery) { - _navigationFixer.StateChanged(entry, oldState, fromQuery); - _localViewListener.StateChanged(entry, oldState, fromQuery); + _navigationFixer?.StateChanged(entry, oldState, fromQuery); + _localViewListener?.StateChanged(entry, oldState, fromQuery); } /// @@ -75,7 +77,7 @@ public virtual void StateChanged(InternalEntityEntry entry, EntityState oldState /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void TrackedFromQuery(InternalEntityEntry entry) - => _navigationFixer.TrackedFromQuery(entry); + => _navigationFixer?.TrackedFromQuery(entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -86,9 +88,9 @@ public virtual void TrackedFromQuery(InternalEntityEntry entry) public virtual void NavigationReferenceChanged( InternalEntityEntry entry, INavigation navigation, - object oldValue, - object newValue) - => _navigationFixer.NavigationReferenceChanged(entry, navigation, oldValue, newValue); + object? oldValue, + object? newValue) + => _navigationFixer?.NavigationReferenceChanged(entry, navigation, oldValue, newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -101,7 +103,7 @@ public virtual void NavigationCollectionChanged( INavigationBase navigationBase, IEnumerable added, IEnumerable removed) - => _navigationFixer.NavigationCollectionChanged(entry, navigationBase, added, removed); + => _navigationFixer?.NavigationCollectionChanged(entry, navigationBase, added, removed); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -114,9 +116,9 @@ public virtual void KeyPropertyChanged( IProperty property, IEnumerable keys, IEnumerable foreignKeys, - object oldValue, - object newValue) - => _navigationFixer.KeyPropertyChanged(entry, property, keys, foreignKeys, oldValue, newValue); + object? oldValue, + object? newValue) + => _navigationFixer?.KeyPropertyChanged(entry, property, keys, foreignKeys, oldValue, newValue); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -125,7 +127,7 @@ public virtual void KeyPropertyChanged( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void PropertyChanged(InternalEntityEntry entry, IPropertyBase property, bool setModified) - => _changeDetector.PropertyChanged(entry, property, setModified); + => _changeDetector?.PropertyChanged(entry, property, setModified); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -134,6 +136,6 @@ public virtual void PropertyChanged(InternalEntityEntry entry, IPropertyBase pro /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual void PropertyChanging(InternalEntityEntry entry, IPropertyBase property) - => _changeDetector.PropertyChanging(entry, property); + => _changeDetector?.PropertyChanging(entry, property); } } diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs index 3842c0d0b53..d7c7cca856a 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntrySubscriber.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.Extensions.DependencyInjection; +#nullable enable + // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { @@ -110,8 +112,8 @@ private static INotifyCollectionChanged AsINotifyCollectionChanged( IEntityType entityType, ChangeTrackingStrategy changeTrackingStrategy) { - if (!(navigation.GetCollectionAccessor() - ?.GetOrCreate(entry.Entity, forMaterialization: false) is INotifyCollectionChanged notifyingCollection)) + if (navigation.GetCollectionAccessor() + ?.GetOrCreate(entry.Entity, forMaterialization: false) is not INotifyCollectionChanged notifyingCollection) { throw new InvalidOperationException( CoreStrings.NonNotifyingCollection(navigation.Name, entityType.DisplayName(), changeTrackingStrategy)); @@ -125,7 +127,7 @@ private static INotifyPropertyChanged AsINotifyPropertyChanged( IEntityType entityType, ChangeTrackingStrategy changeTrackingStrategy) { - if (!(entry.Entity is INotifyPropertyChanged changed)) + if (entry.Entity is not INotifyPropertyChanged changed) { throw new InvalidOperationException( CoreStrings.ChangeTrackingInterfaceMissing( @@ -140,7 +142,7 @@ private static INotifyPropertyChanging AsINotifyPropertyChanging( IEntityType entityType, ChangeTrackingStrategy changeTrackingStrategy) { - if (!(entry.Entity is INotifyPropertyChanging changing)) + if (entry.Entity is not INotifyPropertyChanging changing) { throw new InvalidOperationException( CoreStrings.ChangeTrackingInterfaceMissing( diff --git a/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs index 7ffb0128609..a7904672b27 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalMixedEntityEntry.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -70,7 +72,8 @@ public InternalMixedEntityEntry( /// 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 override T ReadShadowValue(int shadowIndex) + protected override T? ReadShadowValue(int shadowIndex) + where T : default => _shadowValues.GetValue(shadowIndex); /// @@ -79,7 +82,7 @@ protected override T ReadShadowValue(int shadowIndex) /// 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 override object ReadPropertyValue(IPropertyBase propertyBase) + protected override object? ReadPropertyValue(IPropertyBase propertyBase) => !propertyBase.IsShadowProperty() ? base.ReadPropertyValue(propertyBase) : _shadowValues[propertyBase.GetShadowIndex()]; @@ -101,7 +104,7 @@ protected override bool PropertyHasDefaultValue(IPropertyBase propertyBase) /// 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 override void WritePropertyValue(IPropertyBase propertyBase, object value, bool forMaterialization) + protected override void WritePropertyValue(IPropertyBase propertyBase, object? value, bool forMaterialization) { if (!propertyBase.IsShadowProperty()) { diff --git a/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs b/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs index 92987e57a04..6c6024ee64b 100644 --- a/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs +++ b/src/EFCore/ChangeTracking/Internal/KeyPropagator.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.ValueGeneration; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -49,7 +51,7 @@ public KeyPropagator( /// 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 InternalEntityEntry PropagateValue(InternalEntityEntry entry, IProperty property) + public virtual InternalEntityEntry? PropagateValue(InternalEntityEntry entry, IProperty property) { Check.DebugAssert(property.IsForeignKey(), $"property {property} is not part of an FK"); @@ -87,7 +89,7 @@ public virtual InternalEntityEntry PropagateValue(InternalEntityEntry entry, IPr /// 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 async Task PropagateValueAsync( + public virtual async Task PropagateValueAsync( InternalEntityEntry entry, IProperty property, CancellationToken cancellationToken = default) @@ -122,7 +124,7 @@ public virtual async Task PropagateValueAsync( return principalEntry; } - private static InternalEntityEntry TryPropagateValue(InternalEntityEntry entry, IProperty property, IProperty generationProperty) + private static InternalEntityEntry? TryPropagateValue(InternalEntityEntry entry, IProperty property, IProperty? generationProperty) { var entityType = entry.EntityType; var stateManager = entry.StateManager; @@ -136,7 +138,7 @@ private static InternalEntityEntry TryPropagateValue(InternalEntityEntry entry, var principal = foreignKey.DependentToPrincipal == null ? null : entry[foreignKey.DependentToPrincipal]; - InternalEntityEntry principalEntry = null; + InternalEntityEntry? principalEntry = null; if (principal != null) { principalEntry = stateManager.GetOrCreateEntry(principal, foreignKey.PrincipalEntityType); @@ -185,7 +187,7 @@ private static InternalEntityEntry TryPropagateValue(InternalEntityEntry entry, return null; } - private ValueGenerator TryGetValueGenerator(IProperty generationProperty) + private ValueGenerator? TryGetValueGenerator(IProperty? generationProperty) => generationProperty != null ? _valueGeneratorSelector.Select(generationProperty, generationProperty.DeclaringEntityType) : null; diff --git a/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs index 9ccdb0d7e32..c8eee742c9f 100644 --- a/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/KeyValueFactoryFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -24,11 +26,13 @@ public class KeyValueFactoryFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IPrincipalKeyValueFactory Create([NotNull] IKey key) + where TKey : notnull => key.Properties.Count == 1 ? CreateSimpleFactory(key) : (IPrincipalKeyValueFactory)CreateCompositeFactory(key); private static SimplePrincipalKeyValueFactory CreateSimpleFactory(IKey key) + where TKey : notnull { var dependentFactory = new DependentKeyValueFactoryFactory(); var principalKeyValueFactory = new SimplePrincipalKeyValueFactory(key.Properties.Single()); diff --git a/src/EFCore/ChangeTracking/Internal/LocalViewListener.cs b/src/EFCore/ChangeTracking/Internal/LocalViewListener.cs index 6c06e8d6192..31097ce7a0b 100644 --- a/src/EFCore/ChangeTracking/Internal/LocalViewListener.cs +++ b/src/EFCore/ChangeTracking/Internal/LocalViewListener.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs b/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs index 6a09e68ee05..3e66ebbbac0 100644 --- a/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/MultiSnapshot.cs @@ -5,6 +5,8 @@ using System.Reflection; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -37,7 +39,7 @@ internal static readonly ConstructorInfo Constructor /// 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 T GetValue(int index) + public T? GetValue(int index) => _snapshots[index / Snapshot.MaxGenericTypes].GetValue(index % Snapshot.MaxGenericTypes); /// @@ -46,7 +48,7 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { get => _snapshots[index / Snapshot.MaxGenericTypes][index % Snapshot.MaxGenericTypes]; set => _snapshots[index / Snapshot.MaxGenericTypes][index % Snapshot.MaxGenericTypes] = value; diff --git a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs index 506ca30fcc1..335bf263a73 100644 --- a/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs +++ b/src/EFCore/ChangeTracking/Internal/NavigationFixer.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -56,8 +58,8 @@ public NavigationFixer( public virtual void NavigationReferenceChanged( InternalEntityEntry entry, INavigationBase navigationBase, - object oldValue, - object newValue) + object? oldValue, + object? newValue) { if (_inFixup) { @@ -101,7 +103,7 @@ public virtual void NavigationReferenceChanged( // However, if the FK has already been changed or the reference is already set to point // to something else, then don't change it. var victimDependentEntry = - (InternalEntityEntry)stateManager.GetDependents(newTargetEntry, foreignKey).FirstOrDefault(); + (InternalEntityEntry?)stateManager.GetDependents(newTargetEntry, foreignKey).FirstOrDefault(); if (victimDependentEntry != null && victimDependentEntry != entry) { @@ -350,8 +352,8 @@ public virtual void KeyPropertyChanged( IProperty property, IEnumerable containingPrincipalKeys, IEnumerable containingForeignKeys, - object oldValue, - object newValue) + object? oldValue, + object? newValue) { if (entry.EntityState == EntityState.Detached) { @@ -402,7 +404,7 @@ public virtual void KeyPropertyChanged( // However, if the FK has already been changed or the reference is already set to point // to something else, then don't change it. var targetDependentEntry - = (InternalEntityEntry)stateManager + = (InternalEntityEntry?)stateManager .GetDependentsUsingRelationshipSnapshot(newPrincipalEntry, foreignKey).FirstOrDefault(); if (targetDependentEntry != null @@ -672,7 +674,7 @@ private void InitialFixup( var dependents = stateManager.GetDependents(entry, foreignKey); if (foreignKey.IsUnique) { - var dependentEntry = (InternalEntityEntry)dependents.FirstOrDefault(); + var dependentEntry = (InternalEntityEntry?)dependents.FirstOrDefault(); if (dependentEntry != null) { if ((!foreignKey.IsOwnership @@ -950,7 +952,7 @@ private InternalEntityEntry FindOrCreateJoinEntry( return joinEntry; } - private static InternalEntityEntry FindJoinEntry( + private static InternalEntityEntry? FindJoinEntry( InternalEntityEntry entry, InternalEntityEntry otherEntry, ISkipNavigation skipNavigation) @@ -994,7 +996,7 @@ private static InternalEntityEntry FindJoinEntry( .ToList(); var keyProperties = foreignKey.Properties.Concat(otherForeignKey.Properties).ToList(); - var keyComparers = keyProperties.Select(e => e.GetKeyValueComparer()).ToList(); + var keyComparers = keyProperties.Select(e => e.GetKeyValueComparer()!).ToList(); var propertiesCount = keyComparers.Count; foreach (var candidate in entry.StateManager.Entries) @@ -1026,7 +1028,7 @@ bool TryFind( InternalEntityEntry secondEntry, IForeignKey firstForeignKey, IForeignKey secondForeignKey, - out InternalEntityEntry joinEntry) + out InternalEntityEntry? joinEntry) { var key = joinEntityType.FindKey(new[] { firstForeignKey.Properties[0], secondForeignKey.Properties[0] }); if (key != null) @@ -1050,7 +1052,7 @@ bool TryFindComposite( InternalEntityEntry secondEntry, IForeignKey firstForeignKey, IForeignKey secondForeignKey, - out InternalEntityEntry joinEntry) + out InternalEntityEntry? joinEntry) { var firstForeignKeyProperties = firstForeignKey.Properties; var secondForeignKeyProperties = secondForeignKey.Properties; @@ -1058,7 +1060,7 @@ bool TryFindComposite( var key = joinEntityType.FindKey(firstForeignKeyProperties.Concat(secondForeignKeyProperties).ToList()); if (key != null) { - var keyValues = new object[firstForeignKeyProperties.Count + secondForeignKeyProperties.Count]; + var keyValues = new object?[firstForeignKeyProperties.Count + secondForeignKeyProperties.Count]; var index = 0; foreach (var keyProperty in firstForeignKey.PrincipalKey.Properties) @@ -1117,7 +1119,7 @@ private void ToDependentFixup( var oldDependentEntry = oldDependent != null && !ReferenceEquals(dependentEntry.Entity, oldDependent) ? dependentEntry.StateManager.TryGetEntry(oldDependent, foreignKey.DeclaringEntityType) - : (InternalEntityEntry)dependentEntry.StateManager + : (InternalEntityEntry?)dependentEntry.StateManager .GetDependentsUsingRelationshipSnapshot(principalEntry, foreignKey) .FirstOrDefault(); @@ -1185,8 +1187,8 @@ private static void SetForeignKeyProperties( private static bool PrincipalValueEqualsDependentValue( IProperty principalProperty, - object dependentValue, - object principalValue) + object? dependentValue, + object? principalValue) => (principalProperty.GetKeyValueComparer()) ?.Equals(dependentValue, principalValue) ?? StructuralComparisons.StructuralEqualityComparer.Equals( @@ -1195,7 +1197,7 @@ private static bool PrincipalValueEqualsDependentValue( private void ConditionallyNullForeignKeyProperties( InternalEntityEntry dependentEntry, - InternalEntityEntry principalEntry, + InternalEntityEntry? principalEntry, IForeignKey foreignKey) { var principalProperties = foreignKey.PrincipalKey.Properties; @@ -1258,7 +1260,7 @@ private void ConditionallyNullForeignKeyProperties( } } - private void SetNavigation(InternalEntityEntry entry, INavigationBase navigation, InternalEntityEntry value, bool fromQuery) + private void SetNavigation(InternalEntityEntry entry, INavigationBase? navigation, InternalEntityEntry? value, bool fromQuery) { if (navigation != null) { @@ -1277,7 +1279,7 @@ private void SetNavigation(InternalEntityEntry entry, INavigationBase navigation } } - private void AddToCollection(InternalEntityEntry entry, INavigationBase navigation, InternalEntityEntry value, bool fromQuery) + private void AddToCollection(InternalEntityEntry entry, INavigationBase? navigation, InternalEntityEntry value, bool fromQuery) { if (navigation != null) { diff --git a/src/EFCore/ChangeTracking/Internal/NullableClassCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/NullableClassCurrentProviderValueComparer.cs index 8d92c269c02..03daa80b06a 100644 --- a/src/EFCore/ChangeTracking/Internal/NullableClassCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/NullableClassCurrentProviderValueComparer.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -44,8 +46,23 @@ public NullableClassCurrentProviderValueComparer( /// 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 int Compare(IUpdateEntry x, IUpdateEntry y) + public virtual int Compare(IUpdateEntry? x, IUpdateEntry? y) { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + var xValue = x.GetCurrentValue(_property); var yValue = y.GetCurrentValue(_property); diff --git a/src/EFCore/ChangeTracking/Internal/NullableCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/NullableCurrentProviderValueComparer.cs index 3254737605b..307f7c857b3 100644 --- a/src/EFCore/ChangeTracking/Internal/NullableCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/NullableCurrentProviderValueComparer.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -44,8 +46,23 @@ public NullableStructCurrentProviderValueComparer( /// 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 int Compare(IUpdateEntry x, IUpdateEntry y) + public virtual int Compare(IUpdateEntry? x, IUpdateEntry? y) { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + var xValue = x.GetCurrentValue(_property); var yValue = y.GetCurrentValue(_property); diff --git a/src/EFCore/ChangeTracking/Internal/NullableKeyIdentityMap.cs b/src/EFCore/ChangeTracking/Internal/NullableKeyIdentityMap.cs index d2870fd0810..5868fd51bfa 100644 --- a/src/EFCore/ChangeTracking/Internal/NullableKeyIdentityMap.cs +++ b/src/EFCore/ChangeTracking/Internal/NullableKeyIdentityMap.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -15,6 +17,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public class NullableKeyIdentityMap : IdentityMap + where TKey : notnull { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -47,13 +50,13 @@ public override void Add(InternalEntityEntry entry) throw new InvalidOperationException( CoreStrings.InvalidKeyValue( entry.EntityType.DisplayName(), - PrincipalKeyValueFactory.FindNullPropertyInCurrentValues(entry).Name)); + PrincipalKeyValueFactory.FindNullPropertyInCurrentValues(entry)!.Name)); } throw new InvalidOperationException( CoreStrings.InvalidAlternateKeyValue( entry.EntityType.DisplayName(), - PrincipalKeyValueFactory.FindNullPropertyInCurrentValues(entry).Name)); + PrincipalKeyValueFactory.FindNullPropertyInCurrentValues(entry)!.Name)); } Add(key, entry); diff --git a/src/EFCore/ChangeTracking/Internal/OriginalPropertyValues.cs b/src/EFCore/ChangeTracking/Internal/OriginalPropertyValues.cs index b26786cf087..b4c4bc6b707 100644 --- a/src/EFCore/ChangeTracking/Internal/OriginalPropertyValues.cs +++ b/src/EFCore/ChangeTracking/Internal/OriginalPropertyValues.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -32,7 +34,8 @@ public OriginalPropertyValues([NotNull] InternalEntityEntry internalEntry) /// 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 override TValue GetValue(string propertyName) + public override TValue? GetValue(string propertyName) + where TValue: default => InternalEntry.GetOriginalValue(InternalEntry.EntityType.GetProperty(propertyName)); /// @@ -41,7 +44,8 @@ public override TValue GetValue(string propertyName) /// 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 override TValue GetValue(IProperty property) + public override TValue? GetValue(IProperty property) + where TValue : default => InternalEntry.GetOriginalValue(InternalEntry.EntityType.CheckPropertyBelongsToType(property)); /// @@ -50,7 +54,7 @@ public override TValue GetValue(IProperty property) /// 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 override void SetValueInternal(IProperty property, object value) + protected override void SetValueInternal(IProperty property, object? value) => InternalEntry.SetOriginalValue(property, value); /// @@ -59,7 +63,7 @@ protected override void SetValueInternal(IProperty property, object value) /// 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 override object GetValueInternal(IProperty property) + protected override object? GetValueInternal(IProperty property) => InternalEntry.GetOriginalValue(property); } } diff --git a/src/EFCore/ChangeTracking/Internal/OriginalValues.cs b/src/EFCore/ChangeTracking/Internal/OriginalValues.cs index 81dfa753b30..9376a83c5eb 100644 --- a/src/EFCore/ChangeTracking/Internal/OriginalValues.cs +++ b/src/EFCore/ChangeTracking/Internal/OriginalValues.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { public abstract partial class InternalEntityEntry @@ -20,7 +22,7 @@ public OriginalValues(InternalEntityEntry entry) _values = ((IRuntimeEntityType)entry.EntityType).OriginalValuesFactory(entry); } - public object GetValue(InternalEntityEntry entry, IProperty property) + public object? GetValue(InternalEntityEntry entry, IProperty property) { var index = property.GetOriginalValueIndex(); if (index == -1) @@ -32,7 +34,7 @@ public object GetValue(InternalEntityEntry entry, IProperty property) return IsEmpty ? entry[property] : _values[index]; } - public T GetValue(InternalEntityEntry entry, IProperty property, int index) + public T? GetValue(InternalEntityEntry entry, IProperty property, int index) { if (index == -1) { @@ -43,7 +45,7 @@ public T GetValue(InternalEntityEntry entry, IProperty property, int index) return IsEmpty ? entry.GetCurrentValue(property) : _values.GetValue(index); } - public void SetValue(IProperty property, object value, int index) + public void SetValue(IProperty property, object? value, int index) { Check.DebugAssert(!IsEmpty, "Original values are empty"); @@ -103,7 +105,7 @@ public void AcceptChanges(InternalEntityEntry entry) } } - private static object SnapshotValue(IProperty property, object value) + private static object? SnapshotValue(IProperty property, object? value) { var comparer = property.GetValueComparer(); diff --git a/src/EFCore/ChangeTracking/Internal/OriginalValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/OriginalValuesFactoryFactory.cs index d60364905c5..ed45602a99e 100644 --- a/src/EFCore/ChangeTracking/Internal/OriginalValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/OriginalValuesFactoryFactory.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -38,7 +40,7 @@ protected override int GetPropertyCount(IEntityType entityType) /// 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 override ValueComparer GetValueComparer(IProperty property) + protected override ValueComparer? GetValueComparer(IProperty property) => property.GetValueComparer(); } } diff --git a/src/EFCore/ChangeTracking/Internal/RelationshipSnapshotFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/RelationshipSnapshotFactoryFactory.cs index 1e4aab36d4c..bfdb454970c 100644 --- a/src/EFCore/ChangeTracking/Internal/RelationshipSnapshotFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/RelationshipSnapshotFactoryFactory.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -38,7 +40,7 @@ protected override int GetPropertyCount(IEntityType entityType) /// 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 override ValueComparer GetValueComparer(IProperty property) + protected override ValueComparer? GetValueComparer(IProperty property) => property.GetKeyValueComparer(); } } diff --git a/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs b/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs index 8b22b35c6bf..8e8e9595c1a 100644 --- a/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/RelationshipsSnapshot.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { public abstract partial class InternalEntityEntry @@ -20,15 +22,15 @@ public RelationshipsSnapshot(InternalEntityEntry entry) _values = ((IRuntimeEntityType)entry.EntityType).RelationshipSnapshotFactory(entry); } - public object GetValue(InternalEntityEntry entry, IPropertyBase propertyBase) + public object? GetValue(InternalEntityEntry entry, IPropertyBase propertyBase) => IsEmpty ? entry[propertyBase] : _values[propertyBase.GetRelationshipIndex()]; - public T GetValue(InternalEntityEntry entry, IPropertyBase propertyBase, int index) + public T? GetValue(InternalEntityEntry entry, IPropertyBase propertyBase, int index) => IsEmpty ? entry.GetCurrentValue(propertyBase) : _values.GetValue(index); - public void SetValue(IPropertyBase propertyBase, object value) + public void SetValue(IPropertyBase propertyBase, object? value) { if (value == null) { @@ -41,13 +43,13 @@ public void SetValue(IPropertyBase propertyBase, object value) Check.DebugAssert(!IsEmpty, "relationship snapshot is empty"); Check.DebugAssert( - !(propertyBase is INavigation) || !((INavigation)propertyBase).IsCollection, + propertyBase is not INavigation navigation || !navigation.IsCollection, $"property {propertyBase} is is not reference navigation"); _values[propertyBase.GetRelationshipIndex()] = SnapshotValue(propertyBase, value); } - private static object SnapshotValue(IPropertyBase propertyBase, object value) + private static object? SnapshotValue(IPropertyBase propertyBase, object? value) { if (propertyBase is IProperty property) { @@ -67,7 +69,7 @@ public void RemoveFromCollection(IPropertyBase propertyBase, object removedEntit var index = propertyBase.GetRelationshipIndex(); if (index != -1) { - ((HashSet)_values[index])?.Remove(removedEntity); + ((HashSet)_values[index]!)?.Remove(removedEntity); } } @@ -98,7 +100,7 @@ public void AddRangeToCollection(IPropertyBase propertyBase, IEnumerable private HashSet GetOrCreateCollection(int index) { - var snapshot = (HashSet)_values[index]; + var snapshot = (HashSet)_values[index]!; if (snapshot == null) { snapshot = new HashSet(LegacyReferenceEqualityComparer.Instance); diff --git a/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs index b6547e1f71a..e3c92b1cad4 100644 --- a/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/ShadowValuesFactoryFactory.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -41,7 +43,7 @@ protected override int GetPropertyCount(IEntityType entityType) /// 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 override ValueComparer GetValueComparer(IProperty property) + protected override ValueComparer? GetValueComparer(IProperty property) => null; /// diff --git a/src/EFCore/ChangeTracking/Internal/SidecarValues.cs b/src/EFCore/ChangeTracking/Internal/SidecarValues.cs index c4cc484490e..c61ca46789f 100644 --- a/src/EFCore/ChangeTracking/Internal/SidecarValues.cs +++ b/src/EFCore/ChangeTracking/Internal/SidecarValues.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { public abstract partial class InternalEntityEntry @@ -19,7 +21,7 @@ public SidecarValues(ISnapshot valuesFactory) _values = valuesFactory; } - public bool TryGetValue(int index, out object value) + public bool TryGetValue(int index, out object? value) { if (IsEmpty) { @@ -31,10 +33,10 @@ public bool TryGetValue(int index, out object value) return true; } - public T GetValue(int index) + public T? GetValue(int index) => IsEmpty ? default : _values.GetValue(index); - public void SetValue(IProperty property, object value, int index) + public void SetValue(IProperty property, object? value, int index) { Check.DebugAssert(!IsEmpty, "sidecar is empty"); @@ -49,7 +51,7 @@ public void SetValue(IProperty property, object value, int index) _values[index] = SnapshotValue(property, value); } - private static object SnapshotValue(IProperty property, object value) + private static object? SnapshotValue(IProperty property, object? value) { var comparer = property.GetValueComparer(); diff --git a/src/EFCore/ChangeTracking/Internal/SidecarValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/SidecarValuesFactoryFactory.cs index 1ea61c01632..87f18174bb3 100644 --- a/src/EFCore/ChangeTracking/Internal/SidecarValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SidecarValuesFactoryFactory.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -38,7 +40,7 @@ protected override int GetPropertyCount(IEntityType entityType) /// 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 override ValueComparer GetValueComparer(IProperty property) + protected override ValueComparer? GetValueComparer(IProperty property) => property.GetValueComparer(); } } diff --git a/src/EFCore/ChangeTracking/Internal/SimpleFullyNullableDependentKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/SimpleFullyNullableDependentKeyValueFactory.cs index e8384371076..94811f5339a 100644 --- a/src/EFCore/ChangeTracking/Internal/SimpleFullyNullableDependentKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SimpleFullyNullableDependentKeyValueFactory.cs @@ -9,6 +9,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -49,9 +53,9 @@ public SimpleFullyNullableDependentKeyValueFactory( /// 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 bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key) + public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, [CA.NotNullWhen(true)] out TKey? key) { - key = (TKey)_propertyAccessors.ValueBufferGetter(valueBuffer); + key = (TKey)_propertyAccessors.ValueBufferGetter!(valueBuffer); return key != null; } @@ -61,7 +65,7 @@ public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key /// 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 bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = ((Func)_propertyAccessors.CurrentValueGetter)(entry); return key != null; @@ -73,7 +77,7 @@ public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) /// 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 bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = ((Func)_propertyAccessors.PreStoreGeneratedCurrentValueGetter)(entry); return key != null; @@ -85,9 +89,9 @@ public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry ent /// 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 bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = ((Func)_propertyAccessors.OriginalValueGetter)(entry); + key = ((Func)_propertyAccessors.OriginalValueGetter!)(entry); return key != null; } @@ -97,7 +101,7 @@ public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key /// 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 bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = ((Func)_propertyAccessors.RelationshipSnapshotGetter)(entry); return key != null; diff --git a/src/EFCore/ChangeTracking/Internal/SimpleNonNullableDependentKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/SimpleNonNullableDependentKeyValueFactory.cs index a433c1f1a27..4e6f95c5864 100644 --- a/src/EFCore/ChangeTracking/Internal/SimpleNonNullableDependentKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SimpleNonNullableDependentKeyValueFactory.cs @@ -9,6 +9,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -49,9 +53,9 @@ public SimpleNonNullableDependentKeyValueFactory( /// 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 bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key) + public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, [CA.NotNullWhen(true)] out TKey? key) { - var value = _propertyAccessors.ValueBufferGetter(valueBuffer); + var value = _propertyAccessors.ValueBufferGetter!(valueBuffer); if (value == null) { key = default; @@ -68,9 +72,9 @@ public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key /// 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 bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = ((Func)_propertyAccessors.CurrentValueGetter)(entry); + key = ((Func)_propertyAccessors.CurrentValueGetter)(entry)!; return true; } @@ -80,9 +84,9 @@ public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) /// 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 bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = ((Func)_propertyAccessors.PreStoreGeneratedCurrentValueGetter)(entry); + key = ((Func)_propertyAccessors.PreStoreGeneratedCurrentValueGetter)(entry)!; return true; } @@ -92,9 +96,9 @@ public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry ent /// 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 bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = ((Func)_propertyAccessors.OriginalValueGetter)(entry); + key = ((Func)_propertyAccessors.OriginalValueGetter!)(entry)!; return true; } @@ -104,9 +108,9 @@ public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key /// 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 bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = ((Func)_propertyAccessors.RelationshipSnapshotGetter)(entry); + key = ((Func)_propertyAccessors.RelationshipSnapshotGetter)(entry)!; return true; } } diff --git a/src/EFCore/ChangeTracking/Internal/SimpleNullableDependentKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/SimpleNullableDependentKeyValueFactory.cs index b949763659b..1f58cb1ad46 100644 --- a/src/EFCore/ChangeTracking/Internal/SimpleNullableDependentKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SimpleNullableDependentKeyValueFactory.cs @@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -52,7 +54,7 @@ public SimpleNullableDependentKeyValueFactory( /// public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key) { - var value = _propertyAccessors.ValueBufferGetter(valueBuffer); + var value = _propertyAccessors.ValueBufferGetter!(valueBuffer); if (value == null) { key = default; @@ -89,7 +91,7 @@ public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry ent /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key) - => HandleNullableValue(((Func)_propertyAccessors.OriginalValueGetter)(entry), out key); + => HandleNullableValue(((Func)_propertyAccessors.OriginalValueGetter!)(entry), out key); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/SimpleNullablePrincipalDependentKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/SimpleNullablePrincipalDependentKeyValueFactory.cs index 4dde117fb3f..d4eddb88bc4 100644 --- a/src/EFCore/ChangeTracking/Internal/SimpleNullablePrincipalDependentKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SimpleNullablePrincipalDependentKeyValueFactory.cs @@ -9,6 +9,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { // The methods here box, but this is only used when the primary key is nullable, but the FK is non-nullable, @@ -52,9 +56,9 @@ public SimpleNullablePrincipalDependentKeyValueFactory( /// 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 bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key) + public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, [CA.NotNullWhen(true)] out TKey? key) { - var value = _propertyAccessors.ValueBufferGetter(valueBuffer); + var value = _propertyAccessors.ValueBufferGetter!(valueBuffer); if (value == null) { key = default; @@ -71,7 +75,7 @@ public virtual bool TryCreateFromBuffer(in ValueBuffer valueBuffer, out TKey key /// 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 bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = (TKey)(object)((Func)_propertyAccessors.CurrentValueGetter)(entry); return true; @@ -83,7 +87,7 @@ public virtual bool TryCreateFromCurrentValues(IUpdateEntry entry, out TKey key) /// 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 bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = (TKey)(object)((Func)_propertyAccessors.PreStoreGeneratedCurrentValueGetter)(entry); return true; @@ -95,9 +99,9 @@ public virtual bool TryCreateFromPreStoreGeneratedCurrentValues(IUpdateEntry ent /// 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 bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { - key = (TKey)(object)((Func)_propertyAccessors.OriginalValueGetter)(entry); + key = (TKey)(object)((Func)_propertyAccessors.OriginalValueGetter!)(entry); return true; } @@ -107,7 +111,7 @@ public virtual bool TryCreateFromOriginalValues(IUpdateEntry entry, out TKey key /// 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 bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, out TKey key) + public virtual bool TryCreateFromRelationshipSnapshot(IUpdateEntry entry, [CA.NotNullWhen(true)] out TKey? key) { key = (TKey)(object)((Func)_propertyAccessors.RelationshipSnapshotGetter)(entry); return true; diff --git a/src/EFCore/ChangeTracking/Internal/SimplePrincipalKeyValueFactory.cs b/src/EFCore/ChangeTracking/Internal/SimplePrincipalKeyValueFactory.cs index f01edd4f1c6..5f612193db8 100644 --- a/src/EFCore/ChangeTracking/Internal/SimplePrincipalKeyValueFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SimplePrincipalKeyValueFactory.cs @@ -10,6 +10,10 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -50,7 +54,7 @@ public SimplePrincipalKeyValueFactory([NotNull] IProperty property) /// 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 object CreateFromKeyValues(object[] keyValues) + public virtual object? CreateFromKeyValues(object?[] keyValues) => keyValues[0]; /// @@ -59,8 +63,8 @@ public virtual object CreateFromKeyValues(object[] keyValues) /// 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 object CreateFromBuffer(ValueBuffer valueBuffer) - => _propertyAccessors.ValueBufferGetter(valueBuffer); + public virtual object? CreateFromBuffer(ValueBuffer valueBuffer) + => _propertyAccessors.ValueBufferGetter!(valueBuffer); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -68,7 +72,7 @@ public virtual object CreateFromBuffer(ValueBuffer valueBuffer) /// 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 IProperty FindNullPropertyInKeyValues(object[] keyValues) + public virtual IProperty FindNullPropertyInKeyValues(object?[] keyValues) => _property; /// @@ -96,7 +100,7 @@ public virtual IProperty FindNullPropertyInCurrentValues(IUpdateEntry entry) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual TKey CreateFromOriginalValues(IUpdateEntry entry) - => ((Func)_propertyAccessors.OriginalValueGetter)(entry); + => ((Func)_propertyAccessors.OriginalValueGetter!)(entry); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -120,16 +124,16 @@ private sealed class NoNullsStructuralEqualityComparer : IEqualityComparer private readonly IEqualityComparer _comparer = StructuralComparisons.StructuralEqualityComparer; - public bool Equals(TKey x, TKey y) + public bool Equals(TKey? x, TKey? y) => _comparer.Equals(x, y); - public int GetHashCode(TKey obj) + public int GetHashCode([CA.DisallowNull] TKey obj) => _comparer.GetHashCode(obj); } private sealed class NoNullsCustomEqualityComparer : IEqualityComparer { - private readonly Func _equals; + private readonly Func _equals; private readonly Func _hashCode; public NoNullsCustomEqualityComparer(ValueComparer comparer) @@ -140,11 +144,11 @@ public NoNullsCustomEqualityComparer(ValueComparer comparer) comparer = comparer.ToNonNullNullableComparer(); } - _equals = (Func)comparer.EqualsExpression.Compile(); + _equals = (Func)comparer.EqualsExpression.Compile(); _hashCode = (Func)comparer.HashCodeExpression.Compile(); } - public bool Equals(TKey x, TKey y) + public bool Equals(TKey? x, TKey? y) => _equals(x, y); public int GetHashCode(TKey obj) diff --git a/src/EFCore/ChangeTracking/Internal/Snapshot.cs b/src/EFCore/ChangeTracking/Internal/Snapshot.cs index 3d93b46fca8..07023f0b161 100644 --- a/src/EFCore/ChangeTracking/Internal/Snapshot.cs +++ b/src/EFCore/ChangeTracking/Internal/Snapshot.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -41,7 +43,7 @@ private Snapshot() /// 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 object this[int index] + public object? this[int index] { get => throw new IndexOutOfRangeException(); set => throw new IndexOutOfRangeException(); @@ -53,7 +55,7 @@ public object this[int index] /// 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 T GetValue(int index) + public T? GetValue(int index) { throw new IndexOutOfRangeException(); } @@ -90,71 +92,40 @@ public static Delegate[] CreateReaders() /// public static Type CreateSnapshotType([NotNull] Type[] types) { - switch (types.Length) + return types.Length switch { - case 1: - return typeof(Snapshot<>).MakeGenericType(types); - case 2: - return typeof(Snapshot<,>).MakeGenericType(types); - case 3: - return typeof(Snapshot<,,>).MakeGenericType(types); - case 4: - return typeof(Snapshot<,,,>).MakeGenericType(types); - case 5: - return typeof(Snapshot<,,,,>).MakeGenericType(types); - case 6: - return typeof(Snapshot<,,,,,>).MakeGenericType(types); - case 7: - return typeof(Snapshot<,,,,,,>).MakeGenericType(types); - case 8: - return typeof(Snapshot<,,,,,,,>).MakeGenericType(types); - case 9: - return typeof(Snapshot<,,,,,,,,>).MakeGenericType(types); - case 10: - return typeof(Snapshot<,,,,,,,,,>).MakeGenericType(types); - case 11: - return typeof(Snapshot<,,,,,,,,,,>).MakeGenericType(types); - case 12: - return typeof(Snapshot<,,,,,,,,,,,>).MakeGenericType(types); - case 13: - return typeof(Snapshot<,,,,,,,,,,,,>).MakeGenericType(types); - case 14: - return typeof(Snapshot<,,,,,,,,,,,,,>).MakeGenericType(types); - case 15: - return typeof(Snapshot<,,,,,,,,,,,,,,>).MakeGenericType(types); - case 16: - return typeof(Snapshot<,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 17: - return typeof(Snapshot<,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 18: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 19: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 20: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 21: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 22: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 23: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 24: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 25: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 26: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 27: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 28: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 29: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - case 30: - return typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types); - } - - throw new IndexOutOfRangeException(); + 1 => typeof(Snapshot<>).MakeGenericType(types), + 2 => typeof(Snapshot<,>).MakeGenericType(types), + 3 => typeof(Snapshot<,,>).MakeGenericType(types), + 4 => typeof(Snapshot<,,,>).MakeGenericType(types), + 5 => typeof(Snapshot<,,,,>).MakeGenericType(types), + 6 => typeof(Snapshot<,,,,,>).MakeGenericType(types), + 7 => typeof(Snapshot<,,,,,,>).MakeGenericType(types), + 8 => typeof(Snapshot<,,,,,,,>).MakeGenericType(types), + 9 => typeof(Snapshot<,,,,,,,,>).MakeGenericType(types), + 10 => typeof(Snapshot<,,,,,,,,,>).MakeGenericType(types), + 11 => typeof(Snapshot<,,,,,,,,,,>).MakeGenericType(types), + 12 => typeof(Snapshot<,,,,,,,,,,,>).MakeGenericType(types), + 13 => typeof(Snapshot<,,,,,,,,,,,,>).MakeGenericType(types), + 14 => typeof(Snapshot<,,,,,,,,,,,,,>).MakeGenericType(types), + 15 => typeof(Snapshot<,,,,,,,,,,,,,,>).MakeGenericType(types), + 16 => typeof(Snapshot<,,,,,,,,,,,,,,,>).MakeGenericType(types), + 17 => typeof(Snapshot<,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 18 => typeof(Snapshot<,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 19 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 20 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 21 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 22 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 23 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 24 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 25 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 26 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 27 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 28 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 29 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + 30 => typeof(Snapshot<,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>).MakeGenericType(types), + _ => throw new IndexOutOfRangeException(), + }; } } @@ -190,36 +161,36 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24, - [CanBeNull] T25 value25, - [CanBeNull] T26 value26, - [CanBeNull] T27 value27, - [CanBeNull] T28 value28, - [CanBeNull] T29 value29) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24, + [CanBeNull] T25? value25, + [CanBeNull] T26? value26, + [CanBeNull] T27? value27, + [CanBeNull] T28? value28, + [CanBeNull] T29? value29) { _value0 = value0; _value1 = value1; @@ -253,36 +224,36 @@ public Snapshot( _value29 = value29; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; - private T25 _value25; - private T26 _value26; - private T27 _value27; - private T28 _value28; - private T29 _value29; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; + private T25? _value25; + private T26? _value26; + private T27? _value27; + private T28? _value28; + private T29? _value29; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -300,76 +271,42 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - case 25: - return _value25; - case 26: - return _value26; - case 27: - return _value27; - case 28: - return _value28; - case 29: - return _value29; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + 25 => _value25, + 26 => _value26, + 27 => _value27, + 28 => _value28, + 29 => _value29, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -503,35 +440,35 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24, - [CanBeNull] T25 value25, - [CanBeNull] T26 value26, - [CanBeNull] T27 value27, - [CanBeNull] T28 value28) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24, + [CanBeNull] T25? value25, + [CanBeNull] T26? value26, + [CanBeNull] T27? value27, + [CanBeNull] T28? value28) { _value0 = value0; _value1 = value1; @@ -564,35 +501,35 @@ public Snapshot( _value28 = value28; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; - private T25 _value25; - private T26 _value26; - private T27 _value27; - private T28 _value28; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; + private T25? _value25; + private T26? _value26; + private T27? _value27; + private T28? _value28; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -610,74 +547,41 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - case 25: - return _value25; - case 26: - return _value26; - case 27: - return _value27; - case 28: - return _value28; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + 25 => _value25, + 26 => _value26, + 27 => _value27, + 28 => _value28, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -808,34 +712,34 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24, - [CanBeNull] T25 value25, - [CanBeNull] T26 value26, - [CanBeNull] T27 value27) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24, + [CanBeNull] T25? value25, + [CanBeNull] T26? value26, + [CanBeNull] T27? value27) { _value0 = value0; _value1 = value1; @@ -867,34 +771,34 @@ public Snapshot( _value27 = value27; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; - private T25 _value25; - private T26 _value26; - private T27 _value27; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; + private T25? _value25; + private T26? _value26; + private T27? _value27; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -912,72 +816,40 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - case 25: - return _value25; - case 26: - return _value26; - case 27: - return _value27; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + 25 => _value25, + 26 => _value26, + 27 => _value27, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -1105,33 +977,33 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24, - [CanBeNull] T25 value25, - [CanBeNull] T26 value26) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24, + [CanBeNull] T25? value25, + [CanBeNull] T26? value26) { _value0 = value0; _value1 = value1; @@ -1162,33 +1034,33 @@ public Snapshot( _value26 = value26; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; - private T25 _value25; - private T26 _value26; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; + private T25? _value25; + private T26? _value26; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1206,70 +1078,39 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - case 25: - return _value25; - case 26: - return _value26; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + 25 => _value25, + 26 => _value26, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -1394,32 +1235,32 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24, - [CanBeNull] T25 value25) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24, + [CanBeNull] T25? value25) { _value0 = value0; _value1 = value1; @@ -1449,32 +1290,32 @@ public Snapshot( _value25 = value25; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; - private T25 _value25; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; + private T25? _value25; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1492,68 +1333,38 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - case 25: - return _value25; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + 25 => _value25, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -1675,31 +1486,31 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23, - [CanBeNull] T24 value24) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23, + [CanBeNull] T24? value24) { _value0 = value0; _value1 = value1; @@ -1728,31 +1539,31 @@ public Snapshot( _value24 = value24; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; - private T24 _value24; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; + private T24? _value24; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1770,66 +1581,37 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - case 24: - return _value24; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + 24 => _value24, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -1948,30 +1730,30 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22, - [CanBeNull] T23 value23) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22, + [CanBeNull] T23? value23) { _value0 = value0; _value1 = value1; @@ -1999,30 +1781,30 @@ public Snapshot( _value23 = value23; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; - private T23 _value23; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; + private T23? _value23; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2040,64 +1822,36 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - case 23: - return _value23; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + 23 => _value23, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -2212,29 +1966,29 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21, - [CanBeNull] T22 value22) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21, + [CanBeNull] T22? value22) { _value0 = value0; _value1 = value1; @@ -2261,29 +2015,29 @@ public Snapshot( _value22 = value22; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; - private T22 _value22; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; + private T22? _value22; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2301,62 +2055,35 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - case 22: - return _value22; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + 22 => _value22, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -2468,28 +2195,28 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20, - [CanBeNull] T21 value21) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20, + [CanBeNull] T21? value21) { _value0 = value0; _value1 = value1; @@ -2515,28 +2242,28 @@ public Snapshot( _value21 = value21; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; - private T21 _value21; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; + private T21? _value21; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2554,60 +2281,34 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - case 21: - return _value21; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + 21 => _value21, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -2715,27 +2416,27 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19, - [CanBeNull] T20 value20) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19, + [CanBeNull] T20? value20) { _value0 = value0; _value1 = value1; @@ -2760,27 +2461,27 @@ public Snapshot( _value20 = value20; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; - private T20 _value20; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; + private T20? _value20; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2798,58 +2499,33 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - case 20: - return _value20; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + 20 => _value20, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -2953,26 +2629,26 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18, - [CanBeNull] T19 value19) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18, + [CanBeNull] T19? value19) { _value0 = value0; _value1 = value1; @@ -2996,26 +2672,26 @@ public Snapshot( _value19 = value19; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; - private T19 _value19; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; + private T19? _value19; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -3033,56 +2709,32 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - case 19: - return _value19; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + 19 => _value19, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -3183,25 +2835,25 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17, - [CanBeNull] T18 value18) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17, + [CanBeNull] T18? value18) { _value0 = value0; _value1 = value1; @@ -3224,25 +2876,25 @@ public Snapshot( _value18 = value18; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; - private T18 _value18; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; + private T18? _value18; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -3260,54 +2912,31 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - case 18: - return _value18; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + 18 => _value18, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -3405,24 +3034,24 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16, - [CanBeNull] T17 value17) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16, + [CanBeNull] T17? value17) { _value0 = value0; _value1 = value1; @@ -3444,24 +3073,24 @@ public Snapshot( _value17 = value17; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; - private T17 _value17; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; + private T17? _value17; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -3479,52 +3108,30 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - case 17: - return _value17; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + 17 => _value17, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -3619,23 +3226,23 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15, - [CanBeNull] T16 value16) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15, + [CanBeNull] T16? value16) { _value0 = value0; _value1 = value1; @@ -3656,83 +3263,62 @@ public Snapshot( _value16 = value16; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; - private T16 _value16; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; + private T16? _value16; /// /// 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 T GetValue(int index) - => ((Func, T>)_valueReaders[index])(this); - - /// - /// 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 object this[int index] - { - get - { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - case 16: - return _value16; - default: - throw new IndexOutOfRangeException(); - } - } + /// 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 T GetValue(int index) + => ((Func, T>)_valueReaders[index])(this); + + /// + /// 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 object? this[int index] + { + get => index switch + { + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + 16 => _value16, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -3824,22 +3410,22 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14, - [CanBeNull] T15 value15) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14, + [CanBeNull] T15? value15) { _value0 = value0; _value1 = value1; @@ -3859,22 +3445,22 @@ public Snapshot( _value15 = value15; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; - private T15 _value15; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; + private T15? _value15; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -3891,48 +3477,28 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - case 15: - return _value15; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + 15 => _value15, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4021,21 +3587,21 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13, - [CanBeNull] T14 value14) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13, + [CanBeNull] T14? value14) { _value0 = value0; _value1 = value1; @@ -4054,21 +3620,21 @@ public Snapshot( _value14 = value14; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; - private T14 _value14; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; + private T14? _value14; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4085,46 +3651,27 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - case 14: - return _value14; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + 14 => _value14, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4210,20 +3757,20 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12, - [CanBeNull] T13 value13) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12, + [CanBeNull] T13? value13) { _value0 = value0; _value1 = value1; @@ -4241,20 +3788,20 @@ public Snapshot( _value13 = value13; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; - private T13 _value13; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; + private T13? _value13; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4271,44 +3818,26 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - case 13: - return _value13; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + 13 => _value13, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4391,19 +3920,19 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11, - [CanBeNull] T12 value12) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11, + [CanBeNull] T12? value12) { _value0 = value0; _value1 = value1; @@ -4420,19 +3949,19 @@ public Snapshot( _value12 = value12; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; - private T12 _value12; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; + private T12? _value12; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4449,42 +3978,25 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - case 12: - return _value12; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + 12 => _value12, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4564,18 +4076,18 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10, - [CanBeNull] T11 value11) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10, + [CanBeNull] T11? value11) { _value0 = value0; _value1 = value1; @@ -4591,18 +4103,18 @@ public Snapshot( _value11 = value11; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; - private T11 _value11; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; + private T11? _value11; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4619,40 +4131,24 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - case 11: - return _value11; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + 11 => _value11, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4729,17 +4225,17 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9, - [CanBeNull] T10 value10) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9, + [CanBeNull] T10? value10) { _value0 = value0; _value1 = value1; @@ -4754,17 +4250,17 @@ public Snapshot( _value10 = value10; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; - private T10 _value10; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; + private T10? _value10; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4781,38 +4277,23 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - case 10: - return _value10; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + 10 => _value10, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -4886,16 +4367,16 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8, - [CanBeNull] T9 value9) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8, + [CanBeNull] T9? value9) { _value0 = value0; _value1 = value1; @@ -4909,16 +4390,16 @@ public Snapshot( _value9 = value9; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; - private T9 _value9; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; + private T9? _value9; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -4935,36 +4416,22 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - case 9: - return _value9; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + 9 => _value9, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5035,15 +4502,15 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7, - [CanBeNull] T8 value8) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7, + [CanBeNull] T8? value8) { _value0 = value0; _value1 = value1; @@ -5056,15 +4523,15 @@ public Snapshot( _value8 = value8; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; - private T8 _value8; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; + private T8? _value8; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5081,34 +4548,21 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - case 8: - return _value8; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + 8 => _value8, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5176,14 +4630,14 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6, - [CanBeNull] T7 value7) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6, + [CanBeNull] T7? value7) { _value0 = value0; _value1 = value1; @@ -5195,14 +4649,14 @@ public Snapshot( _value7 = value7; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; - private T7 _value7; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; + private T7? _value7; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5219,32 +4673,20 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - case 7: - return _value7; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + 7 => _value7, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5309,13 +4751,13 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5, - [CanBeNull] T6 value6) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5, + [CanBeNull] T6? value6) { _value0 = value0; _value1 = value1; @@ -5326,13 +4768,13 @@ public Snapshot( _value6 = value6; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; - private T6 _value6; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; + private T6? _value6; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5349,30 +4791,19 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - case 6: - return _value6; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + 6 => _value6, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5434,12 +4865,12 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4, - [CanBeNull] T5 value5) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4, + [CanBeNull] T5? value5) { _value0 = value0; _value1 = value1; @@ -5449,12 +4880,12 @@ public Snapshot( _value5 = value5; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; - private T5 _value5; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; + private T5? _value5; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5471,28 +4902,18 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - case 5: - return _value5; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + 5 => _value5, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5551,11 +4972,11 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3, - [CanBeNull] T4 value4) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3, + [CanBeNull] T4? value4) { _value0 = value0; _value1 = value1; @@ -5564,11 +4985,11 @@ public Snapshot( _value4 = value4; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; - private T4 _value4; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; + private T4? _value4; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5585,26 +5006,17 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - case 4: - return _value4; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + 4 => _value4, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5660,10 +5072,10 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2, - [CanBeNull] T3 value3) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2, + [CanBeNull] T3? value3) { _value0 = value0; _value1 = value1; @@ -5671,10 +5083,10 @@ public Snapshot( _value3 = value3; } - private T0 _value0; - private T1 _value1; - private T2 _value2; - private T3 _value3; + private T0? _value0; + private T1? _value1; + private T2? _value2; + private T3? _value3; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5691,24 +5103,16 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - case 3: - return _value3; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + 3 => _value3, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5761,18 +5165,18 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1, - [CanBeNull] T2 value2) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1, + [CanBeNull] T2? value2) { _value0 = value0; _value1 = value1; _value2 = value2; } - private T0 _value0; - private T1 _value1; - private T2 _value2; + private T0? _value0; + private T1? _value1; + private T2? _value2; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5789,22 +5193,15 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - case 2: - return _value2; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + 2 => _value2, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5854,15 +5251,15 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0, - [CanBeNull] T1 value1) + [CanBeNull] T0? value0, + [CanBeNull] T1? value1) { _value0 = value0; _value1 = value1; } - private T0 _value0; - private T1 _value1; + private T0? _value0; + private T1? _value1; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5879,20 +5276,14 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get + get => index switch { - switch (index) - { - case 0: - return _value0; - case 1: - return _value1; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => _value0, + 1 => _value1, + _ => throw new IndexOutOfRangeException(), + }; set { switch (index) @@ -5939,12 +5330,12 @@ public Snapshot() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public Snapshot( - [CanBeNull] T0 value0) + [CanBeNull] T0? value0) { _value0 = value0; } - private T0 _value0; + private T0? _value0; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -5961,29 +5352,18 @@ public T GetValue(int index) /// 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 object this[int index] + public object? this[int index] { - get - { - switch (index) + get => index switch { - case 0: - return _value0; - default: - throw new IndexOutOfRangeException(); - } - } - set - { - switch (index) + 0 => _value0, + _ => throw new IndexOutOfRangeException(), + }; + set => _value0 = index switch { - case 0: - _value0 = (T0)value; - break; - default: - throw new IndexOutOfRangeException(); - } - } + 0 => (T0)value, + _ => throw new IndexOutOfRangeException(), + }; } } } diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs index e2d262de1a8..6af582d2708 100644 --- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -33,7 +35,9 @@ public virtual Func CreateEmpty([NotNull] IEntityType entityType) return GetPropertyCount(entityType) == 0 ? (() => Snapshot.Empty) : Expression.Lambda>( - CreateConstructorExpression(entityType, null)) + // TODO-Nullable: This whole code path is null unsafe. We are passing null parameter but later using parameter + // as if always exists. + CreateConstructorExpression(entityType, null!)) .Compile(); } @@ -45,7 +49,7 @@ public virtual Func CreateEmpty([NotNull] IEntityType entityType) /// protected virtual Expression CreateConstructorExpression( [NotNull] IEntityType entityType, - [CanBeNull] ParameterExpression parameter) + [NotNull] ParameterExpression parameter) { var count = GetPropertyCount(entityType); @@ -99,7 +103,7 @@ protected virtual Expression CreateConstructorExpression( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected virtual Expression CreateSnapshotExpression( - [CanBeNull] Type entityType, + [CanBeNull] Type? entityType, [NotNull] ParameterExpression parameter, [NotNull] Type[] types, [NotNull] IList propertyBases) @@ -135,7 +139,7 @@ protected virtual Expression CreateSnapshotExpression( } var memberInfo = propertyBase.GetMemberInfo(forMaterialization: false, forSet: false); - var memberAccess = PropertyBase.CreateMemberAccess(propertyBase, entityVariable, memberInfo); + var memberAccess = PropertyBase.CreateMemberAccess(propertyBase, entityVariable!, memberInfo); if (memberAccess.Type != propertyBase.ClrType) { @@ -171,7 +175,7 @@ protected virtual Expression CreateSnapshotExpression( entityVariable, Expression.Convert( Expression.Property(parameter, "Entity"), - entityType)), + entityType!)), constructorExpression }) : constructorExpression; @@ -208,7 +212,7 @@ private Expression CreateSnapshotValueExpression(Expression expression, IPropert /// 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 abstract ValueComparer GetValueComparer([NotNull] IProperty property); + protected abstract ValueComparer? GetValueComparer([NotNull] IProperty property); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -217,7 +221,7 @@ private Expression CreateSnapshotValueExpression(Expression expression, IPropert /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected virtual Expression CreateReadShadowValueExpression( - [CanBeNull] ParameterExpression parameter, + [NotNull] ParameterExpression parameter, [NotNull] IPropertyBase property) => Expression.Call( parameter, @@ -231,7 +235,7 @@ protected virtual Expression CreateReadShadowValueExpression( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected virtual Expression CreateReadValueExpression( - [CanBeNull] ParameterExpression parameter, + [NotNull] ParameterExpression parameter, [NotNull] IPropertyBase property) => Expression.Call( parameter, @@ -264,10 +268,10 @@ protected virtual bool UseEntityVariable => true; private static readonly MethodInfo _snapshotCollectionMethod - = typeof(SnapshotFactoryFactory).GetTypeInfo().GetDeclaredMethod(nameof(SnapshotCollection)); + = typeof(SnapshotFactoryFactory).GetTypeInfo().GetRequiredDeclaredMethod(nameof(SnapshotCollection)); [UsedImplicitly] - private static HashSet SnapshotCollection(IEnumerable collection) + private static HashSet? SnapshotCollection(IEnumerable? collection) => collection == null ? null : new HashSet(collection, LegacyReferenceEqualityComparer.Instance); diff --git a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs index 3cd08bc5316..e6a772a08ac 100644 --- a/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs +++ b/src/EFCore/ChangeTracking/Internal/SnapshotFactoryFactory`.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/StateData.cs b/src/EFCore/ChangeTracking/Internal/StateData.cs index e10cedbcae0..e8790ceec20 100644 --- a/src/EFCore/ChangeTracking/Internal/StateData.cs +++ b/src/EFCore/ChangeTracking/Internal/StateData.cs @@ -3,6 +3,8 @@ using System; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { public abstract partial class InternalEntityEntry diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs index 4bb666333eb..9ad8dea5afd 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs @@ -18,6 +18,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { // This is lower-level change tracking services used by the ChangeTracker and other parts of the system @@ -39,12 +41,12 @@ public class StateManager : IStateManager { private readonly EntityReferenceMap _entityReferenceMap = new(hasSubMap: true); - private IDictionary>> _referencedUntrackedEntities; - private IIdentityMap _identityMap0; - private IIdentityMap _identityMap1; - private Dictionary _identityMaps; + private IDictionary>>? _referencedUntrackedEntities; + private IIdentityMap? _identityMap0; + private IIdentityMap? _identityMap1; + private Dictionary? _identityMaps; private bool _needsUnsubscribe; - private IChangeDetector _changeDetector; + private IChangeDetector? _changeDetector; private bool _changeDetectorInitialized; private readonly IDiagnosticsLogger _changeTrackingLogger; @@ -52,7 +54,7 @@ public class StateManager : IStateManager private readonly IInternalEntityEntrySubscriber _internalEntityEntrySubscriber; private readonly IModel _model; private readonly IDatabase _database; - private readonly IConcurrencyDetector _concurrencyDetector; + private readonly IConcurrencyDetector? _concurrencyDetector; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -242,7 +244,7 @@ public virtual InternalEntityEntry GetOrCreateEntry(object entity) /// 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 InternalEntityEntry GetOrCreateEntry(object entity, IEntityType entityType) + public virtual InternalEntityEntry GetOrCreateEntry(object entity, IEntityType? entityType) { if (entityType == null) { @@ -354,7 +356,7 @@ public virtual InternalEntityEntry StartTrackingFromQuery( var entityType = baseEntityType.HasSharedClrType || baseEntityType.ClrType == clrType ? baseEntityType - : _model.FindRuntimeEntityType(clrType); + : _model.FindRuntimeEntityType(clrType)!; var newEntry = valueBuffer.IsEmpty ? _internalEntityEntryFactory.Create(this, entityType, entity) @@ -383,7 +385,7 @@ public virtual InternalEntityEntry StartTrackingFromQuery( /// 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 InternalEntityEntry TryGetEntry(IKey key, object[] keyValues) + public virtual InternalEntityEntry? TryGetEntry(IKey key, object?[] keyValues) => FindIdentityMap(key)?.TryGetEntry(keyValues); /// @@ -392,7 +394,7 @@ public virtual InternalEntityEntry TryGetEntry(IKey key, object[] keyValues) /// 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 InternalEntityEntry TryGetEntry(IKey key, object[] keyValues, bool throwOnNullKey, out bool hasNullKey) + public virtual InternalEntityEntry? TryGetEntry(IKey key, object?[] keyValues, bool throwOnNullKey, out bool hasNullKey) => GetOrCreateIdentityMap(key).TryGetEntry(keyValues, throwOnNullKey, out hasNullKey); /// @@ -401,7 +403,7 @@ public virtual InternalEntityEntry TryGetEntry(IKey key, object[] keyValues, boo /// 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 InternalEntityEntry TryGetEntry(object entity, bool throwOnNonUniqueness = true) + public virtual InternalEntityEntry? TryGetEntry(object entity, bool throwOnNonUniqueness = true) => _entityReferenceMap.TryGet(entity, null, out var entry, throwOnNonUniqueness) ? entry : null; @@ -412,11 +414,12 @@ public virtual InternalEntityEntry TryGetEntry(object entity, bool throwOnNonUni /// 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 InternalEntityEntry TryGetEntry(object entity, IEntityType entityType, bool throwOnTypeMismatch = true) + public virtual InternalEntityEntry? TryGetEntry(object entity, IEntityType entityType, bool throwOnTypeMismatch = true) { var found = _entityReferenceMap.TryGet(entity, entityType, out var entry, throwOnNonUniqueness: false); if (found - && !entityType.IsAssignableFrom(entry.EntityType)) + // TODO-Nullable: Bug in compiler? + && !entityType.IsAssignableFrom(entry!.EntityType)) { if (throwOnTypeMismatch) { @@ -469,7 +472,7 @@ private IIdentityMap GetOrCreateIdentityMap(IKey key) return identityMap; } - private IIdentityMap FindIdentityMap(IKey key) + private IIdentityMap? FindIdentityMap(IKey? key) { if (_identityMap0 == null || key == null) @@ -747,7 +750,7 @@ public virtual IEnumerable> GetRecor /// 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 InternalEntityEntry FindPrincipal( + public virtual InternalEntityEntry? FindPrincipal( InternalEntityEntry dependentEntry, IForeignKey foreignKey) => FilterIncompatiblePrincipal( @@ -761,7 +764,7 @@ public virtual InternalEntityEntry FindPrincipal( /// 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 InternalEntityEntry FindPrincipalUsingPreStoreGeneratedValues( + public virtual InternalEntityEntry? FindPrincipalUsingPreStoreGeneratedValues( InternalEntityEntry dependentEntry, IForeignKey foreignKey) => FilterIncompatiblePrincipal( @@ -775,7 +778,7 @@ public virtual InternalEntityEntry FindPrincipalUsingPreStoreGeneratedValues( /// 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 InternalEntityEntry FindPrincipalUsingRelationshipSnapshot( + public virtual InternalEntityEntry? FindPrincipalUsingRelationshipSnapshot( InternalEntityEntry dependentEntry, IForeignKey foreignKey) => FilterIncompatiblePrincipal( @@ -783,9 +786,9 @@ public virtual InternalEntityEntry FindPrincipalUsingRelationshipSnapshot( FindIdentityMap(foreignKey.PrincipalKey) ?.TryGetEntryUsingRelationshipSnapshot(foreignKey, dependentEntry)); - private static InternalEntityEntry FilterIncompatiblePrincipal( + private static InternalEntityEntry? FilterIncompatiblePrincipal( IForeignKey foreignKey, - InternalEntityEntry principalEntry) + InternalEntityEntry? principalEntry) => principalEntry != null && foreignKey.PrincipalEntityType.IsAssignableFrom(principalEntry.EntityType) ? principalEntry @@ -870,7 +873,7 @@ public virtual IEnumerable GetDependentsUsingRelationshipSnapshot( /// 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 IEnumerable GetDependentsFromNavigation( + public virtual IEnumerable? GetDependentsFromNavigation( IUpdateEntry principalEntry, IForeignKey foreignKey) { @@ -897,7 +900,7 @@ public virtual IEnumerable GetDependentsFromNavigation( } return ((IEnumerable)navigationValue) - .Select(v => TryGetEntry(v, foreignKey.DeclaringEntityType)).Where(e => e != null); + .Select(v => TryGetEntry(v, foreignKey.DeclaringEntityType)).Where(e => e != null).Cast(); } /// @@ -979,7 +982,7 @@ public virtual void CascadeChanges(bool force) /// 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 void CascadeDelete(InternalEntityEntry entry, bool force, IEnumerable foreignKeys = null) + public virtual void CascadeDelete(InternalEntityEntry entry, bool force, IEnumerable? foreignKeys = null) { var doCascadeDelete = force || CascadeDeleteTiming != CascadeTiming.Never; var principalIsDetached = entry.EntityState == EntityState.Detached; @@ -1074,7 +1077,7 @@ private static bool KeysEqual(InternalEntityEntry entry, IForeignKey fk, Interna return true; } - private static bool KeyValuesEqual(IProperty property, object value, object currentValue) + private static bool KeyValuesEqual(IProperty property, object? value, object? currentValue) => (property.GetKeyValueComparer()) ?.Equals(currentValue, value) ?? Equals(currentValue, value); @@ -1265,7 +1268,7 @@ private static void AcceptAllChanges(IReadOnlyList changedEntries) /// 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 event EventHandler Tracked; + public event EventHandler? Tracked; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -1295,7 +1298,7 @@ public virtual void OnTracked(InternalEntityEntry internalEntityEntry, bool from /// 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 event EventHandler StateChanged; + public event EventHandler? StateChanged; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/ChangeTracking/Internal/StateManagerDependencies.cs b/src/EFCore/ChangeTracking/Internal/StateManagerDependencies.cs index 7d494138e8b..3c9a139ee41 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManagerDependencies.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManagerDependencies.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/StateManagerExtensions.cs b/src/EFCore/ChangeTracking/Internal/StateManagerExtensions.cs index 4a0c6e491df..25ad9444951 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManagerExtensions.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManagerExtensions.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// diff --git a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs index 18bd30cc5f0..4682a6353cf 100644 --- a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentProviderValueComparer.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -38,7 +40,7 @@ public StructuralEntryCurrentProviderValueComparer( /// 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 override object GetPropertyValue(IUpdateEntry entry) + protected override object? GetPropertyValue(IUpdateEntry entry) => _converter.ConvertToProvider(base.GetPropertyValue(entry)); } } diff --git a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentValueComparer.cs b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentValueComparer.cs index dacce99d798..74175171d8e 100644 --- a/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentValueComparer.cs +++ b/src/EFCore/ChangeTracking/Internal/StructuralEntryCurrentValueComparer.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -34,8 +36,23 @@ public StructuralEntryCurrentValueComparer([NotNull] IPropertyBase property) /// 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 override int Compare(IUpdateEntry x, IUpdateEntry y) + public override int Compare(IUpdateEntry? x, IUpdateEntry? y) { + if (ReferenceEquals(x, y)) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + var xValue = GetPropertyValue(x); var yValue = GetPropertyValue(y); diff --git a/src/EFCore/ChangeTracking/Internal/TemporaryValuesFactoryFactory.cs b/src/EFCore/ChangeTracking/Internal/TemporaryValuesFactoryFactory.cs index b037d3d8eae..343c171a90f 100644 --- a/src/EFCore/ChangeTracking/Internal/TemporaryValuesFactoryFactory.cs +++ b/src/EFCore/ChangeTracking/Internal/TemporaryValuesFactoryFactory.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -23,7 +25,7 @@ public class TemporaryValuesFactoryFactory : SidecarValuesFactoryFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected override Expression CreateSnapshotExpression( - Type entityType, + Type? entityType, ParameterExpression parameter, Type[] types, IList propertyBases) diff --git a/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs b/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs index 030f0c51aa4..78f68c92eed 100644 --- a/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs +++ b/src/EFCore/ChangeTracking/Internal/ValueComparerExtensions.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -47,7 +49,7 @@ public static ValueComparer ToNonNullNullableComparer([NotNull] this ValueCompar comparer.ExtractSnapshotBody( Expression.Convert(newSnapshotParam, type)), nullableType), - newSnapshotParam)); + newSnapshotParam))!; } private sealed class NonNullNullableValueComparer : ValueComparer @@ -59,9 +61,9 @@ public NonNullNullableValueComparer( LambdaExpression hashCodeExpression, LambdaExpression snapshotExpression) : base( - (Expression>)equalsExpression, + (Expression>)equalsExpression, (Expression>)hashCodeExpression, - (Expression>)snapshotExpression) + (Expression>)snapshotExpression) { } } diff --git a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs index 0ce41b284a5..d4070b04ca5 100644 --- a/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs +++ b/src/EFCore/ChangeTracking/Internal/ValueGenerationManager.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.ValueGeneration; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking.Internal { /// @@ -58,9 +60,9 @@ public ValueGenerationManager( /// 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 InternalEntityEntry Propagate(InternalEntityEntry entry) + public virtual InternalEntityEntry? Propagate(InternalEntityEntry entry) { - InternalEntityEntry chosenPrincipal = null; + InternalEntityEntry? chosenPrincipal = null; foreach (var property in entry.EntityType.GetForeignKeyProperties()) { if (!entry.HasDefaultValue(property)) diff --git a/src/EFCore/ChangeTracking/LocalView.cs b/src/EFCore/ChangeTracking/LocalView.cs index 04959f2af00..98f062b6cd5 100644 --- a/src/EFCore/ChangeTracking/LocalView.cs +++ b/src/EFCore/ChangeTracking/LocalView.cs @@ -15,6 +15,8 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -56,8 +58,8 @@ public class LocalView : IListSource where TEntity : class { - private ObservableBackedBindingList _bindingList; - private ObservableCollection _observable; + private ObservableBackedBindingList? _bindingList; + private ObservableCollection? _observable; private readonly DbContext _context; private int _countChanges; private int? _count; @@ -96,7 +98,7 @@ public virtual ObservableCollection ToObservableCollection() return _observable; } - private void LocalViewCollectionChanged(object _, NotifyCollectionChangedEventArgs args) + private void LocalViewCollectionChanged(object? _, NotifyCollectionChangedEventArgs args) { Check.DebugAssert( args.Action == NotifyCollectionChangedAction.Add || args.Action == NotifyCollectionChangedAction.Remove, @@ -113,13 +115,13 @@ private void LocalViewCollectionChanged(object _, NotifyCollectionChangedEventAr if (args.Action == NotifyCollectionChangedAction.Remove) { - Check.DebugAssert(args.OldItems.Count == 1, $"OldItems.Count is {args.OldItems.Count}"); - _observable.Remove((TEntity)args.OldItems[0]); + Check.DebugAssert(args.OldItems!.Count == 1, $"OldItems.Count is {args.OldItems.Count}"); + _observable!.Remove((TEntity)args.OldItems[0]!); } else { - Check.DebugAssert(args.NewItems.Count == 1, $"NewItems.Count is {args.NewItems.Count}"); - _observable.Add((TEntity)args.NewItems[0]); + Check.DebugAssert(args.NewItems!.Count == 1, $"NewItems.Count is {args.NewItems.Count}"); + _observable!.Add((TEntity)args.NewItems[0]!); } } finally @@ -128,7 +130,7 @@ private void LocalViewCollectionChanged(object _, NotifyCollectionChangedEventAr } } - private void ObservableCollectionChanged(object _, NotifyCollectionChangedEventArgs args) + private void ObservableCollectionChanged(object? _, NotifyCollectionChangedEventArgs args) { if (_triggeringObservableChange) { @@ -148,7 +150,7 @@ private void ObservableCollectionChanged(object _, NotifyCollectionChangedEventA if (args.Action == NotifyCollectionChangedAction.Remove || args.Action == NotifyCollectionChangedAction.Replace) { - foreach (TEntity entity in args.OldItems) + foreach (TEntity entity in args.OldItems!) { Remove(entity); } @@ -157,7 +159,7 @@ private void ObservableCollectionChanged(object _, NotifyCollectionChangedEventA if (args.Action == NotifyCollectionChangedAction.Add || args.Action == NotifyCollectionChangedAction.Replace) { - foreach (TEntity entity in args.NewItems) + foreach (TEntity entity in args.NewItems!) { Add(entity); } @@ -391,19 +393,19 @@ public virtual bool IsReadOnly /// /// Occurs when a property of this collection (such as ) changes. /// - public virtual event PropertyChangedEventHandler PropertyChanged; + public virtual event PropertyChangedEventHandler? PropertyChanged; /// /// Occurs when a property of this collection (such as ) is changing. /// - public virtual event PropertyChangingEventHandler PropertyChanging; + public virtual event PropertyChangingEventHandler? PropertyChanging; /// /// Occurs when the contents of the collection changes, either because an entity /// has been directly added or removed from the collection, or because an entity /// starts being tracked, or because an entity is marked as Deleted. /// - public virtual event NotifyCollectionChangedEventHandler CollectionChanged; + public virtual event NotifyCollectionChangedEventHandler? CollectionChanged; /// /// Raises the event. @@ -441,7 +443,7 @@ private void OnCollectionChanged(NotifyCollectionChangedAction action, object it /// /// The binding list. public virtual BindingList ToBindingList() - => _bindingList ?? (_bindingList = new ObservableBackedBindingList(ToObservableCollection())); + => _bindingList ??= new ObservableBackedBindingList(ToObservableCollection()); /// /// diff --git a/src/EFCore/ChangeTracking/MemberEntry.cs b/src/EFCore/ChangeTracking/MemberEntry.cs index 1dacf22f31b..64e8dfe7aa9 100644 --- a/src/EFCore/ChangeTracking/MemberEntry.cs +++ b/src/EFCore/ChangeTracking/MemberEntry.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -77,7 +79,7 @@ protected MemberEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IPr /// the change tracker is aware of the change and is not required /// for the context to detect the change. /// - public virtual object CurrentValue + public virtual object? CurrentValue { get => InternalEntry[Metadata]; [param: CanBeNull] set => InternalEntry[Metadata] = value; @@ -107,7 +109,7 @@ InternalEntityEntry IInfrastructure.Instance /// /// A string that represents the current object. [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() + public override string? ToString() => base.ToString(); /// @@ -116,7 +118,7 @@ public override string ToString() /// The object to compare with the current object. /// if the specified object is equal to the current object; otherwise, . [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) + public override bool Equals(object? obj) => base.Equals(obj); /// diff --git a/src/EFCore/ChangeTracking/NavigationEntry.cs b/src/EFCore/ChangeTracking/NavigationEntry.cs index bda7d86808c..0334590e6cc 100644 --- a/src/EFCore/ChangeTracking/NavigationEntry.cs +++ b/src/EFCore/ChangeTracking/NavigationEntry.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -52,7 +54,7 @@ protected NavigationEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] private static INavigationBase GetNavigation(InternalEntityEntry internalEntry, string name, bool collection) { - var navigation = (INavigationBase)internalEntry.EntityType.FindNavigation(name) + var navigation = (INavigationBase?)internalEntry.EntityType.FindNavigation(name) ?? internalEntry.EntityType.FindSkipNavigation(name); if (navigation == null) diff --git a/src/EFCore/ChangeTracking/ObservableHashSet.cs b/src/EFCore/ChangeTracking/ObservableHashSet.cs index ca8ca0795fc..b7c705e8583 100644 --- a/src/EFCore/ChangeTracking/ObservableHashSet.cs +++ b/src/EFCore/ChangeTracking/ObservableHashSet.cs @@ -9,6 +9,8 @@ using System.Linq; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -76,17 +78,17 @@ public ObservableHashSet([NotNull] IEnumerable collection, [NotNull] IEqualit /// /// Occurs when a property of this hash set (such as ) changes. /// - public virtual event PropertyChangedEventHandler PropertyChanged; + public virtual event PropertyChangedEventHandler? PropertyChanged; /// /// Occurs when a property of this hash set (such as ) is changing. /// - public virtual event PropertyChangingEventHandler PropertyChanging; + public virtual event PropertyChangingEventHandler? PropertyChanging; /// /// Occurs when the contents of the hash set changes. /// - public virtual event NotifyCollectionChangedEventHandler CollectionChanged; + public virtual event NotifyCollectionChangedEventHandler? CollectionChanged; void ICollection.Add(T item) => Add(item); @@ -152,7 +154,7 @@ public virtual bool Remove(T item) _set.Remove(item); - OnCollectionChanged(NotifyCollectionChangedAction.Remove, item); + OnCollectionChanged(NotifyCollectionChangedAction.Remove, item!); OnCountPropertyChanged(); @@ -206,7 +208,7 @@ public virtual bool Add(T item) _set.Add(item); - OnCollectionChanged(NotifyCollectionChangedAction.Add, item); + OnCollectionChanged(NotifyCollectionChangedAction.Add, item!); OnCountPropertyChanged(); diff --git a/src/EFCore/ChangeTracking/PropertyEntry.cs b/src/EFCore/ChangeTracking/PropertyEntry.cs index 4c0c58ffe68..a105d2de042 100644 --- a/src/EFCore/ChangeTracking/PropertyEntry.cs +++ b/src/EFCore/ChangeTracking/PropertyEntry.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -87,7 +89,7 @@ public virtual bool IsTemporary /// useful in disconnected scenarios where entities are retrieved with one context instance and /// saved with a different context instance. /// - public virtual object OriginalValue + public virtual object? OriginalValue { get => InternalEntry.GetOriginalValue(Metadata); [param: CanBeNull] set => InternalEntry.SetOriginalValue(Metadata, value); diff --git a/src/EFCore/ChangeTracking/PropertyEntry`.cs b/src/EFCore/ChangeTracking/PropertyEntry`.cs index 4645a70aaa7..875f3dd4563 100644 --- a/src/EFCore/ChangeTracking/PropertyEntry`.cs +++ b/src/EFCore/ChangeTracking/PropertyEntry`.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -58,7 +60,7 @@ public PropertyEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IPro /// the change tracker is aware of the change and is not required /// for the context to detect the change. /// - public new virtual TProperty CurrentValue + public new virtual TProperty? CurrentValue { get => InternalEntry.GetCurrentValue(Metadata); [param: CanBeNull] set => base.CurrentValue = value; @@ -70,7 +72,7 @@ public PropertyEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IPro /// useful in disconnected scenarios where entities are retrieved with one context instance and /// saved with a different context instance. /// - public new virtual TProperty OriginalValue + public new virtual TProperty? OriginalValue { get => InternalEntry.GetOriginalValue(Metadata); [param: CanBeNull] set => base.OriginalValue = value; diff --git a/src/EFCore/ChangeTracking/PropertyValues.cs b/src/EFCore/ChangeTracking/PropertyValues.cs index 23df1246e57..749e944747f 100644 --- a/src/EFCore/ChangeTracking/PropertyValues.cs +++ b/src/EFCore/ChangeTracking/PropertyValues.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -99,7 +101,7 @@ protected PropertyValues([NotNull] InternalEntityEntry internalEntry) /// /// /// The dictionary to read values from. - public virtual void SetValues([NotNull] IDictionary values) + public virtual void SetValues([NotNull] IDictionary values) { Check.NotNull(values, nameof(values)); @@ -131,14 +133,14 @@ public virtual IEntityType EntityType /// /// The property name. /// The value of the property. - public abstract object this[[NotNull] string propertyName] { get; [param: CanBeNull] set; } + public abstract object? this[[NotNull] string propertyName] { get; [param: CanBeNull] set; } /// /// Gets or sets the value of the property. /// /// The property. /// The value of the property. - public abstract object this[[NotNull] IProperty property] { get; [param: CanBeNull] set; } + public abstract object? this[[NotNull] IProperty property] { get; [param: CanBeNull] set; } /// /// Gets the value of the property just like using the indexed property getter but @@ -147,7 +149,7 @@ public virtual IEntityType EntityType /// The type of the property. /// The property name. /// The value of the property. - public abstract TValue GetValue([NotNull] string propertyName); + public abstract TValue? GetValue([NotNull] string propertyName); /// /// Try to gets the value of the property just like using the indexed property getter but @@ -158,7 +160,7 @@ public virtual IEntityType EntityType /// The property name. /// The property value if any. /// True if the property exists, otherwise false. - public virtual bool TryGetValue([NotNull] string propertyName, out TValue value) + public virtual bool TryGetValue([NotNull] string propertyName, out TValue? value) { var property = Properties.FirstOrDefault(p => p.Name == propertyName); if (property != null) @@ -178,7 +180,7 @@ public virtual bool TryGetValue([NotNull] string propertyName, out TValu /// The type of the property. /// The property. /// The value of the property. - public abstract TValue GetValue([NotNull] IProperty property); + public abstract TValue? GetValue([NotNull] IProperty property); #region Hidden System.Object members @@ -187,7 +189,7 @@ public virtual bool TryGetValue([NotNull] string propertyName, out TValu /// /// A string that represents the current object. [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() + public override string? ToString() => base.ToString(); /// @@ -196,7 +198,7 @@ public override string ToString() /// The object to compare with the current object. /// if the specified object is equal to the current object; otherwise, . [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) + public override bool Equals(object? obj) => base.Equals(obj); /// diff --git a/src/EFCore/ChangeTracking/ReferenceEntry.cs b/src/EFCore/ChangeTracking/ReferenceEntry.cs index c65b968f00e..3b0d474a434 100644 --- a/src/EFCore/ChangeTracking/ReferenceEntry.cs +++ b/src/EFCore/ChangeTracking/ReferenceEntry.cs @@ -13,6 +13,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -27,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking /// public class ReferenceEntry : NavigationEntry { - private IEntityFinder _finder; + private IEntityFinder? _finder; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -185,7 +187,7 @@ private void SetFkPropertiesModified( } } - private bool AnyFkPropertiesModified(INavigation navigation, object relatedEntity) + private bool AnyFkPropertiesModified(INavigation navigation, object? relatedEntity) { if (relatedEntity == null) { @@ -204,7 +206,7 @@ private bool AnyFkPropertiesModified(INavigation navigation, object relatedEntit /// The of the entity this navigation targets. /// /// An entry for the entity that this navigation targets. - public virtual EntityEntry TargetEntry + public virtual EntityEntry? TargetEntry { get { @@ -220,7 +222,7 @@ public virtual EntityEntry TargetEntry /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - protected virtual InternalEntityEntry GetTargetEntry() + protected virtual InternalEntityEntry? GetTargetEntry() => CurrentValue == null ? null : InternalEntry.StateManager.GetOrCreateEntry(CurrentValue, Metadata.TargetEntityType); diff --git a/src/EFCore/ChangeTracking/ReferenceEntry`.cs b/src/EFCore/ChangeTracking/ReferenceEntry`.cs index 1fed0cbb501..bdcb97437d9 100644 --- a/src/EFCore/ChangeTracking/ReferenceEntry`.cs +++ b/src/EFCore/ChangeTracking/ReferenceEntry`.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// @@ -60,7 +62,7 @@ public ReferenceEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] INa /// The of the entity this navigation targets. /// /// An entry for the entity that owns this navigation targets. - public new virtual EntityEntry TargetEntry + public new virtual EntityEntry? TargetEntry { get { @@ -74,7 +76,7 @@ public ReferenceEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] INa /// the change tracker is aware of the change and is not required /// for the context to detect the change. /// - public new virtual TProperty CurrentValue + public new virtual TProperty? CurrentValue { get => this.GetInfrastructure().GetCurrentValue(Metadata); [param: CanBeNull] set => base.CurrentValue = value; diff --git a/src/EFCore/ChangeTracking/ValueComparer.cs b/src/EFCore/ChangeTracking/ValueComparer.cs index 8f16c996f56..93224ae5c9e 100644 --- a/src/EFCore/ChangeTracking/ValueComparer.cs +++ b/src/EFCore/ChangeTracking/ValueComparer.cs @@ -4,13 +4,13 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; using System.Reflection; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Utilities; -using MethodInfoExtensions = Microsoft.EntityFrameworkCore.Internal.MethodInfoExtensions; + +#nullable enable namespace Microsoft.EntityFrameworkCore.ChangeTracking { @@ -30,32 +30,26 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking /// public abstract class ValueComparer : IEqualityComparer, IEqualityComparer { - private protected static readonly MethodInfo _doubleEqualsMethodInfo - = typeof(double).GetRuntimeMethod(nameof(double.Equals), new[] { typeof(double) }); + private static readonly MethodInfo _doubleEqualsMethodInfo + = typeof(double).GetRequiredRuntimeMethod(nameof(double.Equals), new[] { typeof(double) }); - private protected static readonly MethodInfo _floatEqualsMethodInfo - = typeof(float).GetRuntimeMethod(nameof(float.Equals), new[] { typeof(float) }); + private static readonly MethodInfo _floatEqualsMethodInfo + = typeof(float).GetRequiredRuntimeMethod(nameof(float.Equals), new[] { typeof(float) }); internal static readonly MethodInfo ArrayCopyMethod - = typeof(Array).GetMethods() - .Single( - t => t.Name == nameof(Array.Copy) - && t.GetParameters().Length == 3 - && t.GetParameters()[0].ParameterType == typeof(Array) - && t.GetParameters()[1].ParameterType == typeof(Array) - && t.GetParameters()[2].ParameterType == typeof(int)); + = typeof(Array).GetRequiredRuntimeMethod(nameof(Array.Copy), new[] { typeof(Array), typeof(Array), typeof(int) }); internal static readonly MethodInfo EqualityComparerHashCodeMethod - = typeof(IEqualityComparer).GetRuntimeMethod(nameof(IEqualityComparer.GetHashCode), new[] { typeof(object) }); + = typeof(IEqualityComparer).GetRequiredRuntimeMethod(nameof(IEqualityComparer.GetHashCode), new[] { typeof(object) }); internal static readonly MethodInfo EqualityComparerEqualsMethod - = typeof(IEqualityComparer).GetRuntimeMethod(nameof(IEqualityComparer.Equals), new[] { typeof(object), typeof(object) }); + = typeof(IEqualityComparer).GetRequiredRuntimeMethod(nameof(IEqualityComparer.Equals), new[] { typeof(object), typeof(object) }); internal static readonly MethodInfo ObjectEqualsMethod - = typeof(object).GetRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) }); + = typeof(object).GetRequiredRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) }); internal static readonly MethodInfo ObjectGetHashCodeMethod - = typeof(object).GetRuntimeMethod(nameof(object.GetHashCode), Type.EmptyTypes); + = typeof(object).GetRequiredRuntimeMethod(nameof(object.GetHashCode), Type.EmptyTypes); /// /// Creates a new with the given comparison and @@ -89,7 +83,7 @@ protected ValueComparer( /// The first instance. /// The second instance. /// if they are equal; otherwise. - public new abstract bool Equals(object left, object right); + public new abstract bool Equals(object? left, object? right); /// /// Returns the hash code for the given instance. @@ -111,7 +105,7 @@ protected ValueComparer( /// /// The instance. /// The snapshot. - public abstract object Snapshot([CanBeNull] object instance); + public abstract object? Snapshot([CanBeNull] object? instance); /// /// The comparison expression. @@ -164,8 +158,7 @@ public virtual Expression ExtractEqualsBody( /// /// The new expression. /// The body of the lambda with the parameter replaced. - public virtual Expression ExtractHashCodeBody( - [NotNull] Expression expression) + public virtual Expression ExtractHashCodeBody([NotNull] Expression expression) { Check.NotNull(expression, nameof(expression)); @@ -181,8 +174,7 @@ public virtual Expression ExtractHashCodeBody( /// /// The new expression. /// The body of the lambda with the parameter replaced. - public virtual Expression ExtractSnapshotBody( - [NotNull] Expression expression) + public virtual Expression ExtractSnapshotBody([NotNull] Expression expression) { Check.NotNull(expression, nameof(expression)); @@ -229,7 +221,7 @@ public static ValueComparer CreateDefault([NotNull] Type type, bool favorStructu return (ValueComparer)Activator.CreateInstance( comparerType.MakeGenericType(type), - new object[] { favorStructuralComparisons }); + new object[] { favorStructuralComparisons })!; } internal class DefaultValueComparer : ValueComparer @@ -245,10 +237,10 @@ public override Expression ExtractEqualsBody(Expression leftExpression, Expressi public override Expression ExtractSnapshotBody(Expression expression) => expression; - public override object Snapshot(object instance) + public override object? Snapshot(object? instance) => instance; - public override T Snapshot(T instance) + public override T? Snapshot(T? instance) => instance; } diff --git a/src/EFCore/ChangeTracking/ValueComparer`.cs b/src/EFCore/ChangeTracking/ValueComparer`.cs index aed9255f66f..3c3fb759fa6 100644 --- a/src/EFCore/ChangeTracking/ValueComparer`.cs +++ b/src/EFCore/ChangeTracking/ValueComparer`.cs @@ -10,12 +10,14 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.ChangeTracking { /// /// /// Specifies custom value snapshotting and comparison for - /// CLR types that cannot be compared with + /// CLR types that cannot be compared with /// and/or need a deep copy when taking a snapshot. For example, arrays of primitive types /// will require both if mutation is to be detected. /// @@ -29,9 +31,9 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking /// The type. public class ValueComparer : ValueComparer, IEqualityComparer { - private Func _equals; - private Func _hashCode; - private Func _snapshot; + private Func? _equals; + private Func? _hashCode; + private Func? _snapshot; /// /// Creates a new with a default comparison @@ -56,7 +58,7 @@ public ValueComparer(bool favorStructuralComparisons) /// The comparison expression. /// The associated hash code generator. public ValueComparer( - [NotNull] Expression> equalsExpression, + [NotNull] Expression> equalsExpression, [NotNull] Expression> hashCodeExpression) : this(equalsExpression, hashCodeExpression, CreateDefaultSnapshotExpression(false)) { @@ -78,9 +80,9 @@ public ValueComparer( /// The associated hash code generator. /// The snapshot expression. public ValueComparer( - [NotNull] Expression> equalsExpression, + [NotNull] Expression> equalsExpression, [NotNull] Expression> hashCodeExpression, - [NotNull] Expression> snapshotExpression) + [NotNull] Expression> snapshotExpression) : base(equalsExpression, hashCodeExpression, snapshotExpression) { } @@ -89,7 +91,7 @@ public ValueComparer( /// Creates an expression for equality. /// /// The equality expression. - protected static Expression> CreateDefaultEqualsExpression() + protected static Expression> CreateDefaultEqualsExpression() { var type = typeof(T); var param1 = Expression.Parameter(type, "v1"); @@ -97,7 +99,7 @@ protected static Expression> CreateDefaultEqualsExpression() if (typeof(IStructuralEquatable).IsAssignableFrom(type)) { - return Expression.Lambda>( + return Expression.Lambda>( Expression.Call( Expression.Constant(StructuralComparisons.StructuralEqualityComparer, typeof(IEqualityComparer)), EqualityComparerEqualsMethod, @@ -116,7 +118,7 @@ protected static Expression> CreateDefaultEqualsExpression() || unwrappedType == typeof(object) ) { - return Expression.Lambda>( + return Expression.Lambda>( Expression.Equal(param1, param2), param1, param2); } @@ -143,7 +145,7 @@ protected static Expression> CreateDefaultEqualsExpression() type = type.BaseType; } - return Expression.Lambda>( + return Expression.Lambda>( typedEquals == null ? Expression.Call( ObjectEqualsMethod, @@ -159,7 +161,7 @@ protected static Expression> CreateDefaultEqualsExpression() /// Creates an expression for creating a snapshot of a value. /// /// The snapshot expression. - protected static Expression> CreateDefaultSnapshotExpression(bool favorStructuralComparisons) + protected static Expression> CreateDefaultSnapshotExpression(bool favorStructuralComparisons) { if (!favorStructuralComparisons || !typeof(T).IsArray) @@ -176,15 +178,15 @@ protected static Expression> CreateDefaultSnapshotExpression(bool fav // var destination = new T[length]; // Array.Copy(source, destination, length); // return destination; - return Expression.Lambda>( + return Expression.Lambda>( Expression.Block( new[] { lengthVariable, destinationVariable }, Expression.Assign( lengthVariable, - Expression.Property(sourceParameter, typeof(T).GetProperty(nameof(Array.Length)))), + Expression.Property(sourceParameter, typeof(T).GetRequiredProperty(nameof(Array.Length)))), Expression.Assign( destinationVariable, - Expression.NewArrayBounds(typeof(T).TryGetSequenceType(), lengthVariable)), + Expression.NewArrayBounds(typeof(T).GetSequenceType(), lengthVariable)), Expression.Call( ArrayCopyMethod, sourceParameter, @@ -242,12 +244,12 @@ var expression /// The first instance. /// The second instance. /// if they are equal; otherwise. - public override bool Equals(object left, object right) + public override bool Equals(object? left, object? right) { var v1Null = left == null; var v2Null = right == null; - return v1Null || v2Null ? v1Null && v2Null : Equals((T)left, (T)right); + return v1Null || v2Null ? v1Null && v2Null : Equals((T?)left, (T?)right); } /// @@ -255,7 +257,7 @@ public override bool Equals(object left, object right) /// /// The instance. /// The hash code. - public override int GetHashCode(object instance) + public override int GetHashCode(object? instance) => instance == null ? 0 : GetHashCode((T)instance); /// @@ -264,7 +266,7 @@ public override int GetHashCode(object instance) /// The first instance. /// The second instance. /// if they are equal; otherwise. - public virtual bool Equals(T left, T right) + public virtual bool Equals(T? left, T? right) => NonCapturingLazyInitializer.EnsureInitialized( ref _equals, this, static c => c.EqualsExpression.Compile())(left, right); @@ -290,8 +292,8 @@ public virtual int GetHashCode(T instance) /// /// The instance. /// The snapshot. - public override object Snapshot(object instance) - => instance == null ? null : (object)Snapshot((T)instance); + public override object? Snapshot(object? instance) + => instance == null ? null : (object?)Snapshot((T?)instance); /// /// @@ -306,7 +308,7 @@ public override object Snapshot(object instance) /// /// The instance. /// The snapshot. - public virtual T Snapshot([CanBeNull] T instance) + public virtual T? Snapshot([CanBeNull] T? instance) => NonCapturingLazyInitializer.EnsureInitialized( ref _snapshot, this, static c => c.SnapshotExpression.Compile())(instance); @@ -319,8 +321,8 @@ public override Type Type /// /// The comparison expression. /// - public new virtual Expression> EqualsExpression - => (Expression>)base.EqualsExpression; + public new virtual Expression> EqualsExpression + => (Expression>)base.EqualsExpression; /// /// The hash code expression. @@ -339,7 +341,7 @@ public override Type Type /// reference. /// /// - public new virtual Expression> SnapshotExpression - => (Expression>)base.SnapshotExpression; + public new virtual Expression> SnapshotExpression + => (Expression>)base.SnapshotExpression; } } diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 9ee72c2d56e..68e3326f762 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -2120,8 +2120,8 @@ public static void PropertyChangeDetected( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] IProperty property, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogPropertyChangeDetected(diagnostics); @@ -2165,8 +2165,8 @@ public static void PropertyChangeDetectedSensitive( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] IProperty property, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogPropertyChangeDetectedSensitive(diagnostics); @@ -2219,8 +2219,8 @@ public static void ForeignKeyChangeDetected( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] IProperty property, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogForeignKeyChangeDetected(diagnostics); @@ -2267,8 +2267,8 @@ public static void ForeignKeyChangeDetectedSensitive( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] IProperty property, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogForeignKeyChangeDetectedSensitive(diagnostics); @@ -2533,8 +2533,8 @@ public static void ReferenceChangeDetected( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] INavigation navigation, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogReferenceChangeDetected(diagnostics); @@ -2578,8 +2578,8 @@ public static void ReferenceChangeDetectedSensitive( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] InternalEntityEntry internalEntityEntry, [NotNull] INavigation navigation, - [CanBeNull] object oldValue, - [CanBeNull] object newValue) + [CanBeNull] object? oldValue, + [CanBeNull] object? newValue) { var definition = CoreResources.LogReferenceChangeDetectedSensitive(diagnostics); diff --git a/src/EFCore/Infrastructure/ModelValidator.cs b/src/EFCore/Infrastructure/ModelValidator.cs index ea0b29266f4..754644f4948 100644 --- a/src/EFCore/Infrastructure/ModelValidator.cs +++ b/src/EFCore/Infrastructure/ModelValidator.cs @@ -1040,10 +1040,10 @@ protected virtual void ValidateData([NotNull] IModel model, [NotNull] IDiagnosti } } - var keyValues = new object?[key.Properties.Count]; + var keyValues = new object[key.Properties.Count]; for (var i = 0; i < key.Properties.Count; i++) { - keyValues[i] = seedDatum[key.Properties[i].Name]; + keyValues[i] = seedDatum[key.Properties[i].Name]!; } foreach (var navigation in entityType.GetNavigations().Concat(entityType.GetSkipNavigations())) diff --git a/src/EFCore/Metadata/IKey.cs b/src/EFCore/Metadata/IKey.cs index 7d7f4959393..6f24eddc8d6 100644 --- a/src/EFCore/Metadata/IKey.cs +++ b/src/EFCore/Metadata/IKey.cs @@ -45,6 +45,7 @@ public interface IKey : IReadOnlyKey, IAnnotatable /// /// The type of the key instance. /// The factory. - IPrincipalKeyValueFactory GetPrincipalKeyValueFactory(); + IPrincipalKeyValueFactory GetPrincipalKeyValueFactory() + where TKey : notnull; } } diff --git a/src/EFCore/Metadata/Internal/Key.cs b/src/EFCore/Metadata/Internal/Key.cs index 70a7cf1adbe..cf2bc210487 100644 --- a/src/EFCore/Metadata/Internal/Key.cs +++ b/src/EFCore/Metadata/Internal/Key.cs @@ -175,6 +175,7 @@ public virtual Func IdentityMapFactory /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual IPrincipalKeyValueFactory GetPrincipalKeyValueFactory() + where TKey : notnull => (IPrincipalKeyValueFactory)NonCapturingLazyInitializer.EnsureInitialized( ref _principalKeyValueFactory, this, static key => { diff --git a/src/EFCore/Query/QueryContext.cs b/src/EFCore/Query/QueryContext.cs index 25cec9937a9..7360ad682b6 100644 --- a/src/EFCore/Query/QueryContext.cs +++ b/src/EFCore/Query/QueryContext.cs @@ -72,7 +72,7 @@ public virtual void SetNavigationIsLoaded([NotNull] object entity, [NotNull] INa Check.NotNull(navigation, nameof(navigation)); // InitializeStateManager will populate the field before calling here - _stateManager!.TryGetEntry(entity).SetIsLoaded(navigation); + _stateManager!.TryGetEntry(entity)!.SetIsLoaded(navigation); } /// @@ -136,7 +136,7 @@ public virtual void AddParameter(string name, object? value) public virtual void InitializeStateManager(bool standAlone = false) { Check.DebugAssert( - _stateManager == null, + _stateManager == null, "The 'InitializeStateManager' method has been called multiple times on the current query context. This method is intended to be called only once before query enumeration starts."); _stateManager = standAlone @@ -151,7 +151,7 @@ public virtual void InitializeStateManager(bool standAlone = false) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public virtual InternalEntityEntry TryGetEntry( + public virtual InternalEntityEntry? TryGetEntry( [NotNull] IKey key, [NotNull] object[] keyValues, bool throwOnNullKey, diff --git a/src/EFCore/Update/IUpdateEntry.cs b/src/EFCore/Update/IUpdateEntry.cs index d020b67ba2c..533490e3589 100644 --- a/src/EFCore/Update/IUpdateEntry.cs +++ b/src/EFCore/Update/IUpdateEntry.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Update { /// @@ -23,7 +25,7 @@ public interface IUpdateEntry /// /// The property to set. /// The value to set. - void SetOriginalValue([NotNull] IProperty property, [CanBeNull] object value); + void SetOriginalValue([NotNull] IProperty property, [CanBeNull] object? value); /// /// Marks the given property as modified. @@ -44,7 +46,7 @@ public interface IUpdateEntry /// /// The other entry that has the same key values, if one exists. /// - IUpdateEntry SharedIdentityEntry { get; } + IUpdateEntry? SharedIdentityEntry { get; } /// /// Gets a value indicating if the specified property is modified. If true, the current value assigned @@ -73,14 +75,14 @@ public interface IUpdateEntry /// /// The property to get the value for. /// The value for the property. - object GetCurrentValue([NotNull] IPropertyBase propertyBase); + object? GetCurrentValue([NotNull] IPropertyBase propertyBase); /// /// Gets the value assigned to the property when it was retrieved from the database. /// /// The property to get the value for. /// The value for the property. - object GetOriginalValue([NotNull] IPropertyBase propertyBase); + object? GetOriginalValue([NotNull] IPropertyBase propertyBase); /// /// Gets the value assigned to the property. @@ -88,7 +90,7 @@ public interface IUpdateEntry /// The property to get the value for. /// The type of the property. /// The value for the property. - TProperty GetCurrentValue([NotNull] IPropertyBase propertyBase); + TProperty? GetCurrentValue([NotNull] IPropertyBase propertyBase); /// /// Gets the value assigned to the property when it was retrieved from the database. @@ -96,14 +98,14 @@ public interface IUpdateEntry /// The property to get the value for. /// The type of the property. /// The value for the property. - TProperty GetOriginalValue([NotNull] IProperty property); + TProperty? GetOriginalValue([NotNull] IProperty property); /// /// Assign a store-generated value to the property. /// /// The property to set the value for. /// The value to set. - void SetStoreGeneratedValue([NotNull] IProperty property, [CanBeNull] object value); + void SetStoreGeneratedValue([NotNull] IProperty property, [CanBeNull] object? value); /// /// Gets an for the entity being saved. is an API optimized for @@ -118,14 +120,14 @@ public interface IUpdateEntry /// /// The property to get the value for. /// The value for the property. - object GetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase); + object? GetRelationshipSnapshotValue([NotNull] IPropertyBase propertyBase); /// /// Gets the value assigned to the property before any store-generated values have been applied. /// /// The property to get the value for. /// The value for the property. - object GetPreStoreGeneratedCurrentValue([NotNull] IPropertyBase propertyBase); + object? GetPreStoreGeneratedCurrentValue([NotNull] IPropertyBase propertyBase); /// /// Checks whether the property is conceptually set to null even if the property type is not nullable.