Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate ChangeTracking for nullability #24261

Merged
1 commit merged into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1068,15 +1068,15 @@ 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())
{
equals = Expression.OrElse(
equals,
valueComparer.ExtractEqualsBody(
boundProperty,
boundProperty!,
Expression.Constant(derivedDerivedType.GetDiscriminatorValue(), discriminatorProperty.ClrType)));
}

Expand Down
2 changes: 2 additions & 0 deletions src/EFCore/ChangeTracking/ArrayStructuralComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using System.Linq;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore/ChangeTracking/CascadeTiming.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
Expand Down
10 changes: 6 additions & 4 deletions src/EFCore/ChangeTracking/ChangeTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand Down Expand Up @@ -283,7 +285,7 @@ public virtual void TrackGraph(
return false;
}

n.NodeState(n);
n.NodeState!(n);
smitpatel marked this conversation as resolved.
Show resolved Hide resolved

return n.Entry.State != EntityState.Detached;
});
Expand Down Expand Up @@ -321,7 +323,7 @@ public virtual void TrackGraph(
/// <typeparam name="TState"> The type of the state object. </typeparam>
public virtual void TrackGraph<TState>(
[NotNull] object rootEntity,
[CanBeNull] TState state,
[CanBeNull] TState? state,
[NotNull] Func<EntityEntryGraphNode<TState>, bool> callback)
{
Check.NotNull(rootEntity, nameof(rootEntity));
Expand Down Expand Up @@ -452,7 +454,7 @@ public virtual DebugView DebugView
/// </summary>
/// <returns> A string that represents the current object. </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString()
public override string? ToString()
=> base.ToString();

/// <summary>
Expand All @@ -461,7 +463,7 @@ public override string ToString()
/// <param name="obj"> The object to compare with the current object. </param>
/// <returns> <see langword="true" /> if the specified object is equal to the current object; otherwise, <see langword="false" />. </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> base.Equals(obj);

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/EFCore/ChangeTracking/ChangeTrackerDebugStringOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using System;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand Down
19 changes: 18 additions & 1 deletion src/EFCore/ChangeTracking/ChangeTrackerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Update;

#nullable enable

// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore
{
Expand Down Expand Up @@ -53,8 +55,23 @@ private sealed class EntityEntryComparer : IComparer<InternalEntityEntry>
{
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)
{
Expand Down
16 changes: 9 additions & 7 deletions src/EFCore/ChangeTracking/CollectionEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand All @@ -27,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking
/// </summary>
public class CollectionEntry : NavigationEntry
{
private ICollectionLoader _loader;
private ICollectionLoader? _loader;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -81,9 +83,9 @@ private void LocalDetectChanges()
/// the change tracker is aware of the change and <see cref="ChangeTracker.DetectChanges" /> is not required
/// for the context to detect the change.
/// </summary>
public new virtual IEnumerable CurrentValue
public new virtual IEnumerable? CurrentValue
{
get => (IEnumerable)base.CurrentValue;
get => (IEnumerable?)base.CurrentValue;
[param: CanBeNull] set => base.CurrentValue = value;
}

Expand Down Expand Up @@ -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);

/// <summary>
/// The <see cref="EntityEntry" /> of an entity this navigation targets.
/// </summary>
/// <param name="entity"> The entity to get the entry for. </param>
/// <value> An entry for an entity that this navigation targets. </value>
public virtual EntityEntry FindEntry([NotNull] object entity)
public virtual EntityEntry? FindEntry([NotNull] object entity)
{
var entry = GetInternalTargetEntry(entity);
return entry == null
Expand All @@ -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.
/// </summary>
[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);

Expand Down
6 changes: 4 additions & 2 deletions src/EFCore/ChangeTracking/CollectionEntry`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand Down Expand Up @@ -62,7 +64,7 @@ public CollectionEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IN
/// the change tracker is aware of the change and <see cref="ChangeTracker.DetectChanges" /> is not required
/// for the context to detect the change.
/// </summary>
public new virtual IEnumerable<TRelatedEntity> CurrentValue
public new virtual IEnumerable<TRelatedEntity>? CurrentValue
{
get => this.GetInfrastructure().GetCurrentValue<IEnumerable<TRelatedEntity>>(Metadata);
[param: CanBeNull] set => base.CurrentValue = value;
Expand Down Expand Up @@ -90,7 +92,7 @@ public CollectionEntry([NotNull] InternalEntityEntry internalEntry, [NotNull] IN
/// </summary>
/// <param name="entity"> The entity to get the entry for. </param>
/// <value> An entry for an entity that this navigation targets. </value>
public new virtual EntityEntry<TRelatedEntity> FindEntry([NotNull] object entity)
public new virtual EntityEntry<TRelatedEntity>? FindEntry([NotNull] object entity)
{
var entry = GetInternalTargetEntry(entity);
return entry == null
Expand Down
16 changes: 9 additions & 7 deletions src/EFCore/ChangeTracking/EntityEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand All @@ -33,7 +35,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking
public class EntityEntry : IInfrastructure<InternalEntityEntry>
{
private static readonly int _maxEntityState = Enum.GetValues(typeof(EntityState)).Cast<int>().Max();
private IEntityFinder _finder;
private IEntityFinder? _finder;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -345,7 +347,7 @@ public virtual PropertyValues OriginalValues
/// </para>
/// </summary>
/// <returns> The store values, or null if the entity does not exist in the database. </returns>
public virtual PropertyValues GetDatabaseValues()
public virtual PropertyValues? GetDatabaseValues()
{
var values = Finder.GetDatabaseValues(InternalEntry);

Expand All @@ -372,7 +374,7 @@ public virtual PropertyValues GetDatabaseValues()
/// or <see langword="null" /> if the entity does not exist in the database.
/// </returns>
/// <exception cref="OperationCanceledException"> If the <see cref="CancellationToken"/> is canceled. </exception>
public virtual async Task<PropertyValues> GetDatabaseValuesAsync(CancellationToken cancellationToken = default)
public virtual async Task<PropertyValues?> GetDatabaseValuesAsync(CancellationToken cancellationToken = default)
{
var values = await Finder.GetDatabaseValuesAsync(InternalEntry, cancellationToken)
.ConfigureAwait(false);
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -463,7 +465,7 @@ public virtual DebugView DebugView
/// <param name="obj"> The object to compare with the current object. </param>
/// <returns> <see langword="true" /> if the specified object is equal to the current object; otherwise, <see langword="false" />. </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> base.Equals(obj);

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion src/EFCore/ChangeTracking/EntityEntryEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand All @@ -14,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking
public class EntityEntryEventArgs : EventArgs
{
private readonly InternalEntityEntry _internalEntityEntry;
private EntityEntry _entry;
private EntityEntry? _entry;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
14 changes: 9 additions & 5 deletions src/EFCore/ChangeTracking/EntityEntryGraphNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

using CA = System.Diagnostics.CodeAnalysis;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand All @@ -22,7 +26,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking
public class EntityEntryGraphNode : IInfrastructure<InternalEntityEntry>
{
private readonly InternalEntityEntry _entry;
private readonly InternalEntityEntry _sourceEntry;
private readonly InternalEntityEntry? _sourceEntry;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand All @@ -34,8 +38,8 @@ public class EntityEntryGraphNode : IInfrastructure<InternalEntityEntry>
[EntityFrameworkInternal]
public EntityEntryGraphNode(
[NotNull] InternalEntityEntry entry,
[CanBeNull] InternalEntityEntry sourceEntry,
[CanBeNull] INavigationBase inboundNavigation)
[CanBeNull] InternalEntityEntry? sourceEntry,
[CanBeNull] INavigationBase? inboundNavigation)
{
Check.NotNull(entry, nameof(entry));

Expand All @@ -53,7 +57,7 @@ public EntityEntryGraphNode(
/// See <see cref="M:ChangeTracker.TrackGraph" /> for information on how graph nodes are used.
/// </para>
/// </summary>
public virtual EntityEntry SourceEntry
public virtual EntityEntry? SourceEntry
=> _sourceEntry == null ? null : new EntityEntry(_sourceEntry);

/// <summary>
Expand All @@ -64,7 +68,7 @@ public virtual EntityEntry SourceEntry
/// See <see cref="M:ChangeTracker.TrackGraph" /> for information on how graph nodes are used.
/// </para>
/// </summary>
public virtual INavigationBase InboundNavigation { get; }
public virtual INavigationBase? InboundNavigation { get; }

/// <summary>
/// <para>
Expand Down
10 changes: 6 additions & 4 deletions src/EFCore/ChangeTracking/EntityEntryGraphNode`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand All @@ -26,9 +28,9 @@ public class EntityEntryGraphNode<TState> : 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;
Expand All @@ -37,7 +39,7 @@ public EntityEntryGraphNode(
/// <summary>
/// Gets or sets state that will be available to all nodes that are visited after this node.
/// </summary>
public virtual TState NodeState { get; [param: CanBeNull] set; }
public virtual TState? NodeState { get; [param: CanBeNull] set; }

/// <summary>
/// Creates a new node for the entity that is being traversed next in the graph.
Expand Down
4 changes: 3 additions & 1 deletion src/EFCore/ChangeTracking/EntityEntry`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

#nullable enable

namespace Microsoft.EntityFrameworkCore.ChangeTracking
{
/// <summary>
Expand Down Expand Up @@ -155,7 +157,7 @@ public virtual PropertyEntry<TEntity, TProperty> Property<TProperty>(
return new PropertyEntry<TEntity, TProperty>(InternalEntry, propertyName);
}

private static void ValidateType<TProperty>(IProperty property)
private static void ValidateType<TProperty>(IProperty? property)
{
if (property != null
&& property.ClrType != typeof(TProperty))
Expand Down
Loading