diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
index 5bf2882b31d..4f82ac800b9 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
@@ -565,6 +565,8 @@ protected override ShapedQueryExpression TranslateJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
return null;
@@ -618,6 +620,8 @@ protected override ShapedQueryExpression TranslateLeftJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
return null;
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingReadItemExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingReadItemExpressionVisitor.cs
index 3c95dd9364a..a89c430083a 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingReadItemExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingReadItemExpressionVisitor.cs
@@ -1,8 +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.
-using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Query;
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
index 3b85b524b31..0e1ae7ce05c 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
@@ -122,7 +122,7 @@ public override Expression Visit(Expression expression)
_queryableMethodTranslatingExpressionVisitor.TranslateSubquery(
materializeCollectionNavigationExpression.Subquery),
materializeCollectionNavigationExpression.Navigation,
- null);
+ materializeCollectionNavigationExpression.Navigation.ClrType.TryGetSequenceType());
case MethodCallExpression methodCallExpression:
{
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
index db9df7c7130..489dcae9b15 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
@@ -560,6 +560,8 @@ protected override ShapedQueryExpression TranslateJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
(outerKeySelector, innerKeySelector) = ProcessJoinKeySelector(outer, inner, outerKeySelector, innerKeySelector);
@@ -726,6 +728,8 @@ protected override ShapedQueryExpression TranslateLeftJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
(outerKeySelector, innerKeySelector) = ProcessJoinKeySelector(outer, inner, outerKeySelector, innerKeySelector);
diff --git a/src/EFCore.InMemory/Storage/InMemoryDatabaseRoot.cs b/src/EFCore.InMemory/Storage/InMemoryDatabaseRoot.cs
index 4f53ba64e9e..5d0654927db 100644
--- a/src/EFCore.InMemory/Storage/InMemoryDatabaseRoot.cs
+++ b/src/EFCore.InMemory/Storage/InMemoryDatabaseRoot.cs
@@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Storage
/// across context instances and service providers as long as the same instance
/// of this type is passed to
///
+ /// cref="InMemoryDbContextOptionsExtensions.UseInMemoryDatabase{TContext}(DbContextOptionsBuilder{TContext},string,System.Action{InMemoryDbContextOptionsBuilder})" />
///
public sealed class InMemoryDatabaseRoot
{
diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs
index 9880fccc1c0..0e3ac1966c0 100644
--- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs
@@ -639,7 +639,7 @@ public static void SetCommandTimeout([NotNull] this DatabaseFacade databaseFacad
///
///
/// This is a sugar method allowing a to be used to set the value. It delegates to
- /// .
+ /// .
///
///
/// The for the context.
diff --git a/src/EFCore.Relational/Query/Internal/RelationalProjectionBindingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/RelationalProjectionBindingExpressionVisitor.cs
index f245bff2b3a..e15ceee0707 100644
--- a/src/EFCore.Relational/Query/Internal/RelationalProjectionBindingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/RelationalProjectionBindingExpressionVisitor.cs
@@ -163,7 +163,8 @@ public override Expression Visit(Expression expression)
return _selectExpression.AddCollectionProjection(
_queryableMethodTranslatingExpressionVisitor.TranslateSubquery(
materializeCollectionNavigationExpression.Subquery),
- materializeCollectionNavigationExpression.Navigation, null);
+ materializeCollectionNavigationExpression.Navigation,
+ materializeCollectionNavigationExpression.Navigation.ClrType.TryGetSequenceType());
case MethodCallExpression methodCallExpression:
{
diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
index 2ff0452beab..dac3deb55ab 100644
--- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
@@ -586,6 +586,8 @@ protected override ShapedQueryExpression TranslateJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
var joinPredicate = CreateJoinPredicate(outer, outerKeySelector, inner, innerKeySelector);
@@ -611,6 +613,8 @@ protected override ShapedQueryExpression TranslateLeftJoin(
{
Check.NotNull(outer, nameof(outer));
Check.NotNull(inner, nameof(inner));
+ Check.NotNull(outerKeySelector, nameof(outerKeySelector));
+ Check.NotNull(innerKeySelector, nameof(innerKeySelector));
Check.NotNull(resultSelector, nameof(resultSelector));
var joinPredicate = CreateJoinPredicate(outer, outerKeySelector, inner, innerKeySelector);
diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
index 506ac1815ab..51e4e57e795 100644
--- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
+++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
@@ -1332,7 +1332,7 @@ static Expression RemoveConvert(Expression expression)
public CollectionShaperExpression AddCollectionProjection(
[NotNull] ShapedQueryExpression shapedQueryExpression,
[CanBeNull] INavigationBase navigation,
- [CanBeNull] Type elementType)
+ [NotNull] Type elementType)
{
Check.NotNull(shapedQueryExpression, nameof(shapedQueryExpression));
diff --git a/src/EFCore.Relational/Storage/RelationalConnection.cs b/src/EFCore.Relational/Storage/RelationalConnection.cs
index 47c6d79b428..522429c9677 100644
--- a/src/EFCore.Relational/Storage/RelationalConnection.cs
+++ b/src/EFCore.Relational/Storage/RelationalConnection.cs
@@ -233,7 +233,7 @@ public virtual void EnlistTransaction(Transaction transaction)
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
/// The transaction to be used.
@@ -322,7 +322,7 @@ public virtual IDbContextTransaction BeginTransaction(IsolationLevel isolationLe
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
/// The isolation level to use for the transaction.
@@ -376,7 +376,7 @@ public virtual async Task BeginTransactionAsync(
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
/// The isolation level to use for the transaction.
@@ -682,7 +682,7 @@ private void OpenInternal(bool errorsExpected)
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
/// Indicates if the connection errors are expected and should be logged as debug message.
@@ -836,7 +836,7 @@ public virtual bool Close()
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
protected virtual void CloseDbConnection()
@@ -988,7 +988,7 @@ public virtual async ValueTask DisposeAsync()
}
///
- /// Template method that by default calls but can be overriden
+ /// Template method that by default calls but can be overriden
/// by providers to make a different call instead.
///
protected virtual ValueTask DisposeDbConnectionAsync()
diff --git a/src/EFCore.Relational/Storage/RelationalDataReader.cs b/src/EFCore.Relational/Storage/RelationalDataReader.cs
index c6d16ecbecf..58e438a7bbf 100644
--- a/src/EFCore.Relational/Storage/RelationalDataReader.cs
+++ b/src/EFCore.Relational/Storage/RelationalDataReader.cs
@@ -76,7 +76,7 @@ public virtual DbCommand DbCommand
=> _command;
///
- /// Calls on the underlying .
+ /// Calls on the underlying .
///
/// if there are more rows; otherwise .
public virtual bool Read()
@@ -87,7 +87,7 @@ public virtual bool Read()
}
///
- /// Calls on the underlying
+ /// Calls on the underlying
/// .
///
/// if there are more rows; otherwise .
diff --git a/src/EFCore.Relational/Storage/StringTypeMapping.cs b/src/EFCore.Relational/Storage/StringTypeMapping.cs
index 8f1460378a7..5410a6988cf 100644
--- a/src/EFCore.Relational/Storage/StringTypeMapping.cs
+++ b/src/EFCore.Relational/Storage/StringTypeMapping.cs
@@ -22,7 +22,7 @@ public class StringTypeMapping : RelationalTypeMapping
/// Initializes a new instance of the class.
///
/// The name of the database type.
- /// The to be used.
+ /// The to be used.
/// A value indicating whether the type should handle Unicode data or not.
/// The size of data the property is configured to store, or null if no size is configured.
public StringTypeMapping(
diff --git a/src/EFCore.Relational/Update/ModificationCommand.cs b/src/EFCore.Relational/Update/ModificationCommand.cs
index a5d027d1db6..c90a4c19101 100644
--- a/src/EFCore.Relational/Update/ModificationCommand.cs
+++ b/src/EFCore.Relational/Update/ModificationCommand.cs
@@ -99,9 +99,9 @@ public virtual IReadOnlyList Entries
///
/// The that indicates whether the row will be
- /// inserted (),
- /// updated (),
- /// or deleted (().
+ /// inserted (),
+ /// updated (),
+ /// or deleted (().
///
public virtual EntityState EntityState
{
diff --git a/src/EFCore.SqlServer/Scaffolding/Internal/SqlDataReaderExtension.cs b/src/EFCore.SqlServer/Scaffolding/Internal/SqlDataReaderExtension.cs
index 15abddbfb8d..32015ae2fb1 100644
--- a/src/EFCore.SqlServer/Scaffolding/Internal/SqlDataReaderExtension.cs
+++ b/src/EFCore.SqlServer/Scaffolding/Internal/SqlDataReaderExtension.cs
@@ -21,7 +21,7 @@ public static class SqlDataReaderExtension
/// 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.
///
- [return: CA.MaybeNullAttribute]
+ [return: CA.MaybeNull]
public static T GetValueOrDefault([NotNull] this DbDataReader reader, [NotNull] string name)
{
var idx = reader.GetOrdinal(name);
@@ -36,7 +36,7 @@ public static T GetValueOrDefault([NotNull] this DbDataReader reader, [NotNul
/// 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.
///
- [return: CA.MaybeNullAttribute]
+ [return: CA.MaybeNull]
public static T GetValueOrDefault([NotNull] this DbDataRecord record, [NotNull] string name)
{
var idx = record.GetOrdinal(name);
diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs
index 37dc0fc2560..6e4bcead4a7 100644
--- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs
+++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs
@@ -21,7 +21,7 @@ public class SqliteStringTypeMapping : StringTypeMapping
/// Initializes a new instance of the class.
///
/// The name of the database type.
- /// The to be used.
+ /// The to be used.
/// A value indicating whether the type should handle Unicode data or not.
/// The size of data the property is configured to store, or null if no size is configured.
public SqliteStringTypeMapping(
diff --git a/src/EFCore/ChangeTracking/ChangeTracker.cs b/src/EFCore/ChangeTracking/ChangeTracker.cs
index e5574dcc7de..37ca85169e8 100644
--- a/src/EFCore/ChangeTracking/ChangeTracker.cs
+++ b/src/EFCore/ChangeTracking/ChangeTracker.cs
@@ -105,7 +105,7 @@ public ChangeTracker(
/// and methods.
///
///
- /// The default value is . This means the change tracker will
+ /// The default value is . This means the change tracker will
/// keep track of changes for all entities that are returned from a LINQ query.
///
///
@@ -203,7 +203,7 @@ private void TryDetectChanges()
///
/// Checks if any new, deleted, or changed entities are being tracked
/// such that these changes will be sent to the database if
- /// or is called.
+ /// or is called.
///
///
/// Note that this method calls unless
diff --git a/src/EFCore/ChangeTracking/NavigationEntry.cs b/src/EFCore/ChangeTracking/NavigationEntry.cs
index 0e33c71d88b..69537450dc8 100644
--- a/src/EFCore/ChangeTracking/NavigationEntry.cs
+++ b/src/EFCore/ChangeTracking/NavigationEntry.cs
@@ -144,7 +144,7 @@ private static INavigationBase GetNavigation(InternalEntityEntry internalEntry,
/// Loading entities from the database using
/// or
///
+ /// cref="EntityFrameworkQueryableExtensions.ThenInclude{TEntity,TPreviousProperty,TProperty}(Query.IIncludableQueryable{TEntity,IEnumerable{TPreviousProperty}},System.Linq.Expressions.Expression{Func{TPreviousProperty,TProperty}})" />
/// , , or will set this flag. Subsequent calls to
/// or will then be a no-op.
///
diff --git a/src/EFCore/DbContext.cs b/src/EFCore/DbContext.cs
index d63a38ec922..867e43d97f2 100644
--- a/src/EFCore/DbContext.cs
+++ b/src/EFCore/DbContext.cs
@@ -448,9 +448,9 @@ protected internal virtual void OnModelCreating(ModelBuilder modelBuilder)
/// Saves all changes made in this context to the database.
///
///
- /// This method will automatically call to discover any
+ /// This method will automatically call to discover any
/// changes to entity instances before saving to the underlying database. This can be disabled via
- /// .
+ /// .
///
///
///
@@ -472,13 +472,13 @@ public virtual int SaveChanges()
/// Saves all changes made in this context to the database.
///
///
- /// This method will automatically call to discover any
+ /// This method will automatically call to discover any
/// changes to entity instances before saving to the underlying database. This can be disabled via
- /// .
+ /// .
///
///
///
- /// Indicates whether is called after the changes have
+ /// Indicates whether is called after the changes have
/// been sent successfully to the database.
///
///
@@ -555,9 +555,9 @@ private void TryDetectChanges(EntityEntry entry)
/// Saves all changes made in this context to the database.
///
///
- /// This method will automatically call to discover any
+ /// This method will automatically call to discover any
/// changes to entity instances before saving to the underlying database. This can be disabled via
- /// .
+ /// .
///
///
/// Multiple active operations on the same context instance are not supported. Use 'await' to ensure
@@ -585,9 +585,9 @@ public virtual Task SaveChangesAsync(CancellationToken cancellationToken =
/// Saves all changes made in this context to the database.
///
///
- /// This method will automatically call to discover any
+ /// This method will automatically call to discover any
/// changes to entity instances before saving to the underlying database. This can be disabled via
- /// .
+ /// .
///
///
/// Multiple active operations on the same context instance are not supported. Use 'await' to ensure
@@ -595,7 +595,7 @@ public virtual Task SaveChangesAsync(CancellationToken cancellationToken =
///
///
///
- /// Indicates whether is called after the changes have
+ /// Indicates whether is called after the changes have
/// been sent successfully to the database.
///
/// A to observe while waiting for the task to complete.
@@ -1010,7 +1010,7 @@ await SetEntityStateAsync(entry.GetInfrastructure(), EntityState.Added, cancella
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1053,7 +1053,7 @@ public virtual EntityEntry Attach([NotNull] TEntity entity)
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1215,7 +1215,7 @@ await SetEntityStateAsync(entry.GetInfrastructure(), EntityState.Added, cancella
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1256,7 +1256,7 @@ public virtual EntityEntry Attach([NotNull] object entity)
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1387,7 +1387,7 @@ public virtual Task AddRangeAsync([NotNull] params object[] entities)
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1424,7 +1424,7 @@ public virtual void AttachRange([NotNull] params object[] entities)
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1543,7 +1543,7 @@ await SetEntityStateAsync(
/// when a different state will be used.
///
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
@@ -1580,7 +1580,7 @@ public virtual void AttachRange([NotNull] IEnumerable
///
- /// Generally, no database interaction will be performed until is called.
+ /// Generally, no database interaction will be performed until is called.
///
///
/// A recursive search of the navigation properties will be performed to find reachable entities
diff --git a/src/EFCore/DbContextOptionsBuilder.cs b/src/EFCore/DbContextOptionsBuilder.cs
index 096d423cd0f..fb18095fbee 100644
--- a/src/EFCore/DbContextOptionsBuilder.cs
+++ b/src/EFCore/DbContextOptionsBuilder.cs
@@ -117,7 +117,7 @@ public virtual DbContextOptionsBuilder UseLoggerFactory([CanBeNull] ILoggerFacto
/// This overload allows the minimum level of logging and the log formatting to be controlled.
/// Use the
///
+ /// cref="LogTo(Action{string},IEnumerable{EventId},LogLevel,DbContextLoggerOptions?)" />
/// overload to log only specific events.
/// Use the
/// overload to log only events in specific categories.
@@ -459,7 +459,7 @@ public virtual DbContextOptionsBuilder EnableServiceProviderCaching(bool cacheSe
/// and methods.
///
///
- /// The default value is . This means
+ /// The default value is . This means
/// the change tracker will keep track of changes for all entities that are returned from a LINQ query.
///
///
diff --git a/src/EFCore/DbContextOptionsBuilder`.cs b/src/EFCore/DbContextOptionsBuilder`.cs
index dba16ee93cb..11d82d37ebe 100644
--- a/src/EFCore/DbContextOptionsBuilder`.cs
+++ b/src/EFCore/DbContextOptionsBuilder`.cs
@@ -93,7 +93,7 @@ public DbContextOptionsBuilder([NotNull] DbContextOptions options)
/// This overload allows the minimum level of logging and the log formatting to be controlled.
/// Use the
///
+ /// cref="LogTo(Action{string},IEnumerable{EventId},LogLevel,DbContextLoggerOptions?)" />
/// overload to log only specific events.
/// Use the
/// overload to log only events in specific categories.
@@ -345,7 +345,7 @@ public DbContextOptionsBuilder([NotNull] DbContextOptions options)
/// and methods.
///
///
- /// The default value is . This means the
+ /// The default value is . This means the
/// change tracker will keep track of changes for all entities that are returned from a LINQ query.
///
///
diff --git a/src/EFCore/Diagnostics/EventDefinitionBase.cs b/src/EFCore/Diagnostics/EventDefinitionBase.cs
index 11150e259ca..9cfda6b11b6 100644
--- a/src/EFCore/Diagnostics/EventDefinitionBase.cs
+++ b/src/EFCore/Diagnostics/EventDefinitionBase.cs
@@ -18,7 +18,7 @@ public abstract class EventDefinitionBase
/// Creates an event definition instance.
///
/// Logging options.
- /// The .
+ /// The .
/// The at which the event will be logged.
///
/// A string representing the code that should be passed to .
diff --git a/src/EFCore/Metadata/Builders/ReferenceCollectionBuilder`.cs b/src/EFCore/Metadata/Builders/ReferenceCollectionBuilder`.cs
index a1a9616a291..262917dbf8c 100644
--- a/src/EFCore/Metadata/Builders/ReferenceCollectionBuilder`.cs
+++ b/src/EFCore/Metadata/Builders/ReferenceCollectionBuilder`.cs
@@ -70,7 +70,7 @@ protected ReferenceCollectionBuilder(
/// of the entity class.
///
///
- /// If is not specified,
+ /// If is not specified,
/// then an attempt will be made to match the data type and order of foreign key properties against
/// the primary key of the principal entity type. If they do not match, new shadow state properties
/// that form a unique index will be added to the principal entity type to serve as the reference key.
diff --git a/src/EFCore/Metadata/Builders/ReferenceReferenceBuilder.cs b/src/EFCore/Metadata/Builders/ReferenceReferenceBuilder.cs
index 4388b599652..d8499abdead 100644
--- a/src/EFCore/Metadata/Builders/ReferenceReferenceBuilder.cs
+++ b/src/EFCore/Metadata/Builders/ReferenceReferenceBuilder.cs
@@ -83,7 +83,7 @@ public virtual ReferenceReferenceBuilder HasAnnotation([NotNull] string annotati
/// of the entity class.
///
///
- /// If is not specified, then an attempt will be made to
+ /// If is not specified, then an attempt will be made to
/// match the data type and order of foreign key properties against the primary key of the principal
/// entity type. If they do not match, new shadow state properties that form a unique index will be
/// added to the principal entity type to serve as the reference key.
@@ -121,7 +121,7 @@ public virtual ReferenceReferenceBuilder HasForeignKey(
/// of the entity class.
///
///
- /// If is not specified, then an attempt will be made to
+ /// If is not specified, then an attempt will be made to
/// match the data type and order of foreign key properties against the primary key of the principal
/// entity type. If they do not match, new shadow state properties that form a unique index will be
/// added to the principal entity type to serve as the reference key.
diff --git a/src/EFCore/Properties/TypeForwards.cs b/src/EFCore/Properties/TypeForwards.cs
index 8b4fb17ee75..10e904d3c71 100644
--- a/src/EFCore/Properties/TypeForwards.cs
+++ b/src/EFCore/Properties/TypeForwards.cs
@@ -6,7 +6,7 @@
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
-[assembly: TypeForwardedToAttribute(typeof(ObservableBackedBindingList<>))]
-[assembly: TypeForwardedToAttribute(typeof(ObservableCollectionExtensions))]
-[assembly: TypeForwardedToAttribute(typeof(ObservableCollectionListSource<>))]
-[assembly: TypeForwardedToAttribute(typeof(SortableBindingList<>))]
+[assembly: TypeForwardedTo(typeof(ObservableBackedBindingList<>))]
+[assembly: TypeForwardedTo(typeof(ObservableCollectionExtensions))]
+[assembly: TypeForwardedTo(typeof(ObservableCollectionListSource<>))]
+[assembly: TypeForwardedTo(typeof(SortableBindingList<>))]
diff --git a/src/EFCore/Query/CollectionShaperExpression.cs b/src/EFCore/Query/CollectionShaperExpression.cs
index ce6aeec7449..de7be628ee5 100644
--- a/src/EFCore/Query/CollectionShaperExpression.cs
+++ b/src/EFCore/Query/CollectionShaperExpression.cs
@@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -31,8 +33,8 @@ public class CollectionShaperExpression : Expression, IPrintableExpression
public CollectionShaperExpression(
[NotNull] Expression projection,
[NotNull] Expression innerShaper,
- [CanBeNull] INavigationBase navigation,
- [CanBeNull] Type elementType)
+ [CanBeNull] INavigationBase? navigation,
+ [NotNull] Type elementType)
{
Check.NotNull(projection, nameof(projection));
Check.NotNull(innerShaper, nameof(innerShaper));
@@ -40,7 +42,7 @@ public CollectionShaperExpression(
Projection = projection;
InnerShaper = innerShaper;
Navigation = navigation;
- ElementType = elementType ?? navigation.ClrType.TryGetSequenceType();
+ ElementType = elementType;
}
///
@@ -56,7 +58,7 @@ public CollectionShaperExpression(
///
/// The navigation if associated with the collection.
///
- public virtual INavigationBase Navigation { get; }
+ public virtual INavigationBase? Navigation { get; }
///
/// The clr type of elements of the collection.
diff --git a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs
index bdd5241c170..3f97e5554f3 100644
--- a/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs
+++ b/src/EFCore/Query/CompiledQueryCacheKeyGenerator.cs
@@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -112,7 +114,7 @@ public CompiledQueryCacheKey(
/// if the object is a and is for the same query, otherwise
/// .
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj is CompiledQueryCacheKey other && Equals(other);
///
diff --git a/src/EFCore/Query/CompiledQueryCacheKeyGeneratorDependencies.cs b/src/EFCore/Query/CompiledQueryCacheKeyGeneratorDependencies.cs
index 956cc7cdf9e..38515f511d2 100644
--- a/src/EFCore/Query/CompiledQueryCacheKeyGeneratorDependencies.cs
+++ b/src/EFCore/Query/CompiledQueryCacheKeyGeneratorDependencies.cs
@@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/EntityShaperExpression.cs b/src/EFCore/Query/EntityShaperExpression.cs
index 3fd1cc92700..5e3ae2344c5 100644
--- a/src/EFCore/Query/EntityShaperExpression.cs
+++ b/src/EFCore/Query/EntityShaperExpression.cs
@@ -15,6 +15,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -64,7 +66,7 @@ protected EntityShaperExpression(
[NotNull] IEntityType entityType,
[NotNull] Expression valueBufferExpression,
bool nullable,
- [CanBeNull] LambdaExpression materializationCondition)
+ [CanBeNull] LambdaExpression? materializationCondition)
{
Check.NotNull(entityType, nameof(entityType));
Check.NotNull(valueBufferExpression, nameof(valueBufferExpression));
@@ -251,7 +253,8 @@ public virtual EntityShaperExpression Update([NotNull] Expression valueBufferExp
///
public override Type Type
- => EntityType.ClrType;
+ // No shadow entities at runtime
+ => EntityType.ClrType!;
///
public sealed override ExpressionType NodeType
diff --git a/src/EFCore/Query/EvaluatableExpressionFilter.cs b/src/EFCore/Query/EvaluatableExpressionFilter.cs
index 34eaffa5b7d..29e1ca767d9 100644
--- a/src/EFCore/Query/EvaluatableExpressionFilter.cs
+++ b/src/EFCore/Query/EvaluatableExpressionFilter.cs
@@ -10,6 +10,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs b/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs
index d7f7d6e9b4a..f7e8d46ccd4 100644
--- a/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs
+++ b/src/EFCore/Query/EvaluatableExpressionFilterDependencies.cs
@@ -7,6 +7,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/ExpressionEqualityComparer.cs b/src/EFCore/Query/ExpressionEqualityComparer.cs
index 98a464fa993..f964780639c 100644
--- a/src/EFCore/Query/ExpressionEqualityComparer.cs
+++ b/src/EFCore/Query/ExpressionEqualityComparer.cs
@@ -8,6 +8,8 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
+#nullable enable
+
// ReSharper disable SwitchStatementMissingSomeCases
// ReSharper disable ForCanBeConvertedToForeach
// ReSharper disable LoopCanBeConvertedToQuery
diff --git a/src/EFCore/Query/ExpressionPrinter.cs b/src/EFCore/Query/ExpressionPrinter.cs
index 020c7cfdadb..38f8cdfe66a 100644
--- a/src/EFCore/Query/ExpressionPrinter.cs
+++ b/src/EFCore/Query/ExpressionPrinter.cs
@@ -12,6 +12,9 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query
{
@@ -81,7 +84,7 @@ public ExpressionPrinter()
/// A join action to use when joining printout of individual item in the collection.
public virtual void VisitCollection(
[NotNull] IReadOnlyCollection items,
- [CanBeNull] Action joinAction = null)
+ [CanBeNull] Action? joinAction = null)
where T : Expression
{
Check.NotNull(items, nameof(items));
@@ -216,7 +219,8 @@ public virtual string GenerateBinaryOperator(ExpressionType expressionType)
}
///
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression == null)
{
@@ -697,7 +701,7 @@ var argumentNames
: method.GetParameters().Select(p => p.Name).ToList()
: new List();
- IDisposable indent = null;
+ IDisposable? indent = null;
if (!isSimpleMethodOrProperty)
{
@@ -779,7 +783,7 @@ protected override Expression VisitNew(NewExpression newExpression)
appendAction("{ ");
}
- IDisposable indent = null;
+ IDisposable? indent = null;
if (isComplex)
{
indent = _stringBuilder.Indent();
@@ -819,12 +823,12 @@ protected override Expression VisitNewArray(NewArrayExpression newArrayExpressio
Check.NotNull(newArrayExpression, nameof(newArrayExpression));
var isComplex = newArrayExpression.Expressions.Count > 1;
- var appendAction = isComplex ? (Func)AppendLine : Append;
+ var appendAction = isComplex ? s => AppendLine(s) : (Action)(s => Append(s));
appendAction("new " + newArrayExpression.Type.GetElementType().ShortDisplayName() + "[]");
appendAction("{ ");
- IDisposable indent = null;
+ IDisposable? indent = null;
if (isComplex)
{
indent = _stringBuilder.Indent();
@@ -994,7 +998,6 @@ protected override Expression VisitIndex(IndexExpression indexExpression)
indexExpression.Arguments, s =>
{
_stringBuilder.Append(s);
- return null;
});
_stringBuilder.Append("]");
@@ -1075,7 +1078,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
private void VisitArguments(
IReadOnlyList arguments,
- Func appendAction,
+ Action appendAction,
string lastSeparator = "",
bool areConnected = false)
{
diff --git a/src/EFCore/Query/GroupByShaperExpression.cs b/src/EFCore/Query/GroupByShaperExpression.cs
index d399e95437e..29d387b0d10 100644
--- a/src/EFCore/Query/GroupByShaperExpression.cs
+++ b/src/EFCore/Query/GroupByShaperExpression.cs
@@ -7,6 +7,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IAsyncQueryProvider.cs b/src/EFCore/Query/IAsyncQueryProvider.cs
index cd81996de41..7311c232a33 100644
--- a/src/EFCore/Query/IAsyncQueryProvider.cs
+++ b/src/EFCore/Query/IAsyncQueryProvider.cs
@@ -7,6 +7,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/ICompiledQueryCacheKeyGenerator.cs b/src/EFCore/Query/ICompiledQueryCacheKeyGenerator.cs
index 46eebd1a0e4..fb74bc059d1 100644
--- a/src/EFCore/Query/ICompiledQueryCacheKeyGenerator.cs
+++ b/src/EFCore/Query/ICompiledQueryCacheKeyGenerator.cs
@@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IEntityMaterializerSource.cs b/src/EFCore/Query/IEntityMaterializerSource.cs
index 1dd57bd9fb0..fc7320bfba7 100644
--- a/src/EFCore/Query/IEntityMaterializerSource.cs
+++ b/src/EFCore/Query/IEntityMaterializerSource.cs
@@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IEvaluatableExpressionFilter.cs b/src/EFCore/Query/IEvaluatableExpressionFilter.cs
index 5cc64d4a090..92b057e6340 100644
--- a/src/EFCore/Query/IEvaluatableExpressionFilter.cs
+++ b/src/EFCore/Query/IEvaluatableExpressionFilter.cs
@@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IEvaluatableExpressionFilterPlugin.cs b/src/EFCore/Query/IEvaluatableExpressionFilterPlugin.cs
index f5c0588e05a..41fd74b5e74 100644
--- a/src/EFCore/Query/IEvaluatableExpressionFilterPlugin.cs
+++ b/src/EFCore/Query/IEvaluatableExpressionFilterPlugin.cs
@@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IIncludableQueryable.cs b/src/EFCore/Query/IIncludableQueryable.cs
index bb1cc694e19..4de67f415cd 100644
--- a/src/EFCore/Query/IIncludableQueryable.cs
+++ b/src/EFCore/Query/IIncludableQueryable.cs
@@ -3,6 +3,8 @@
using System.Linq;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IPrintableExpression.cs b/src/EFCore/Query/IPrintableExpression.cs
index fc4f28ae87b..9e234012bea 100644
--- a/src/EFCore/Query/IPrintableExpression.cs
+++ b/src/EFCore/Query/IPrintableExpression.cs
@@ -3,6 +3,8 @@
using JetBrains.Annotations;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryCompilationContextFactory.cs b/src/EFCore/Query/IQueryCompilationContextFactory.cs
index 74a05adabe9..d3c910b4347 100644
--- a/src/EFCore/Query/IQueryCompilationContextFactory.cs
+++ b/src/EFCore/Query/IQueryCompilationContextFactory.cs
@@ -3,6 +3,8 @@
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryContextFactory.cs b/src/EFCore/Query/IQueryContextFactory.cs
index f74b9265832..ec1bc3028e9 100644
--- a/src/EFCore/Query/IQueryContextFactory.cs
+++ b/src/EFCore/Query/IQueryContextFactory.cs
@@ -3,6 +3,8 @@
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryTranslationPostprocessorFactory.cs b/src/EFCore/Query/IQueryTranslationPostprocessorFactory.cs
index eb89acbeeec..3fcefba6224 100644
--- a/src/EFCore/Query/IQueryTranslationPostprocessorFactory.cs
+++ b/src/EFCore/Query/IQueryTranslationPostprocessorFactory.cs
@@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryTranslationPreprocessorFactory.cs b/src/EFCore/Query/IQueryTranslationPreprocessorFactory.cs
index dd5c48f0fc5..c2511155259 100644
--- a/src/EFCore/Query/IQueryTranslationPreprocessorFactory.cs
+++ b/src/EFCore/Query/IQueryTranslationPreprocessorFactory.cs
@@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore/Query/IQueryableMethodTranslatingExpressionVisitorFactory.cs
index 13c86adfaaf..b63b43c90cd 100644
--- a/src/EFCore/Query/IQueryableMethodTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore/Query/IQueryableMethodTranslatingExpressionVisitorFactory.cs
@@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IQueryingEnumerable.cs b/src/EFCore/Query/IQueryingEnumerable.cs
index f66f9a9163e..222e90d82a4 100644
--- a/src/EFCore/Query/IQueryingEnumerable.cs
+++ b/src/EFCore/Query/IQueryingEnumerable.cs
@@ -3,6 +3,8 @@
using System.Collections;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IShapedQueryCompilingExpressionVisitorFactory.cs b/src/EFCore/Query/IShapedQueryCompilingExpressionVisitorFactory.cs
index a9468692c41..ec726cf0a04 100644
--- a/src/EFCore/Query/IShapedQueryCompilingExpressionVisitorFactory.cs
+++ b/src/EFCore/Query/IShapedQueryCompilingExpressionVisitorFactory.cs
@@ -4,6 +4,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/IncludeExpression.cs b/src/EFCore/Query/IncludeExpression.cs
index 3459faa4db3..6af33aee150 100644
--- a/src/EFCore/Query/IncludeExpression.cs
+++ b/src/EFCore/Query/IncludeExpression.cs
@@ -7,6 +7,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/Internal/CompiledQueryBase.cs b/src/EFCore/Query/Internal/CompiledQueryBase.cs
index a873d9ab2f6..0e129da1048 100644
--- a/src/EFCore/Query/Internal/CompiledQueryBase.cs
+++ b/src/EFCore/Query/Internal/CompiledQueryBase.cs
@@ -11,6 +11,8 @@
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
@@ -24,7 +26,7 @@ public abstract class CompiledQueryBase
{
private readonly LambdaExpression _queryExpression;
- private Func _executor;
+ private Func? _executor;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Query/Internal/CompiledQueryCache.cs b/src/EFCore/Query/Internal/CompiledQueryCache.cs
index a8ac848fcc3..5609a6c8862 100644
--- a/src/EFCore/Query/Internal/CompiledQueryCache.cs
+++ b/src/EFCore/Query/Internal/CompiledQueryCache.cs
@@ -8,6 +8,8 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/EntityMaterializerSource.cs b/src/EFCore/Query/Internal/EntityMaterializerSource.cs
index 5b3697f5803..0dd6fa1defb 100644
--- a/src/EFCore/Query/Internal/EntityMaterializerSource.cs
+++ b/src/EFCore/Query/Internal/EntityMaterializerSource.cs
@@ -16,6 +16,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
@@ -33,7 +35,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
///
public class EntityMaterializerSource : IEntityMaterializerSource
{
- private ConcurrentDictionary> _materializers;
+ private ConcurrentDictionary>? _materializers;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -66,7 +68,7 @@ public virtual Expression CreateMaterializeExpression(
throw new InvalidOperationException(CoreStrings.CannotMaterializeAbstractType(entityType));
}
- var constructorBinding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding];
+ var constructorBinding = (InstantiationBinding?)entityType[CoreAnnotationNames.ConstructorBinding];
if (constructorBinding == null)
{
@@ -149,7 +151,8 @@ static Expression CreateMemberAssignment(Expression parameter, MemberInfo member
private ConcurrentDictionary> Materializers
=> LazyInitializer.EnsureInitialized(
- ref _materializers,
+ // TODO: Even though we should be able to pass nullable here for some reason it is inferring generic type incorrectly
+ ref _materializers!,
() => new ConcurrentDictionary>());
///
diff --git a/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs b/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs
index 1e513672fac..d0c23f82398 100644
--- a/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs
+++ b/src/EFCore/Query/Internal/EntityMaterializerSourceDependencies.cs
@@ -4,6 +4,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/EntityQueryProvider.cs b/src/EFCore/Query/Internal/EntityQueryProvider.cs
index 8169f96721d..d7f0607ec25 100644
--- a/src/EFCore/Query/Internal/EntityQueryProvider.cs
+++ b/src/EFCore/Query/Internal/EntityQueryProvider.cs
@@ -9,6 +9,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/EntityQueryable`.cs b/src/EFCore/Query/Internal/EntityQueryable`.cs
index d5e48862357..3b5acab127f 100644
--- a/src/EFCore/Query/Internal/EntityQueryable`.cs
+++ b/src/EFCore/Query/Internal/EntityQueryable`.cs
@@ -14,6 +14,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/ICompiledQueryCache.cs b/src/EFCore/Query/Internal/ICompiledQueryCache.cs
index 28dd751ca2e..df76c14e653 100644
--- a/src/EFCore/Query/Internal/ICompiledQueryCache.cs
+++ b/src/EFCore/Query/Internal/ICompiledQueryCache.cs
@@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/IParameterValues.cs b/src/EFCore/Query/Internal/IParameterValues.cs
index ca63c1aa943..25ff48999f3 100644
--- a/src/EFCore/Query/Internal/IParameterValues.cs
+++ b/src/EFCore/Query/Internal/IParameterValues.cs
@@ -4,6 +4,8 @@
using System.Collections.Generic;
using JetBrains.Annotations;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/IQueryCompiler.cs b/src/EFCore/Query/Internal/IQueryCompiler.cs
index f3edcba39e4..a615ca585aa 100644
--- a/src/EFCore/Query/Internal/IQueryCompiler.cs
+++ b/src/EFCore/Query/Internal/IQueryCompiler.cs
@@ -7,6 +7,8 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/InvocationExpressionRemovingExpressionVisitor.cs b/src/EFCore/Query/Internal/InvocationExpressionRemovingExpressionVisitor.cs
index 8068906679b..2ed5607b6e2 100644
--- a/src/EFCore/Query/Internal/InvocationExpressionRemovingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/InvocationExpressionRemovingExpressionVisitor.cs
@@ -6,6 +6,8 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
index 94cf9a181ac..083b991507d 100644
--- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
+++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
@@ -12,6 +12,9 @@
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
@@ -97,7 +100,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return base.VisitMethodCall(methodCallExpression);
}
- private Expression TryExpandNavigation(Expression root, MemberIdentity memberIdentity)
+ private Expression? TryExpandNavigation(Expression root, MemberIdentity memberIdentity)
{
var innerExpression = root.UnwrapTypeConversion(out var convertedType);
if (UnwrapEntityReference(innerExpression) is EntityReference entityReference)
@@ -204,8 +207,9 @@ protected Expression ExpandSkipNavigation(
{
// First pseudo-navigation is a reference
// ExpandFK handles both collection & reference navigation for second psuedo-navigation
+ // Value known to be non-null
secondaryExpansion = ExpandForeignKey(
- primaryExpansion, UnwrapEntityReference(primaryExpansion), inverseNavigation.ForeignKey,
+ primaryExpansion, UnwrapEntityReference(primaryExpansion)!, inverseNavigation.ForeignKey,
!inverseNavigation.IsOnDependent, derivedTypeConversion: false);
}
else
@@ -222,7 +226,8 @@ protected Expression ExpandSkipNavigation(
if (includeTree != null)
{
- UnwrapEntityReference(innerSource.PendingSelector).IncludePaths.Merge(includeTree);
+ // Value known to be non-null
+ UnwrapEntityReference(innerSource.PendingSelector)!.IncludePaths.Merge(includeTree);
}
var sourceElementType = primaryExpansion.Type.GetSequenceType();
@@ -269,7 +274,8 @@ protected Expression ExpandSkipNavigation(
if (includeTree != null)
{
- UnwrapEntityReference(innerSource.PendingSelector).IncludePaths.Merge(includeTree);
+ // Value known to be non-null
+ UnwrapEntityReference(innerSource.PendingSelector)!.IncludePaths.Merge(includeTree);
}
var sourceElementType = primaryExpansion.Type.GetSequenceType();
@@ -337,7 +343,8 @@ private Expression ExpandForeignKey(
// We detect and copy over include for navigation being expanded automatically
var navigation = onDependent ? foreignKey.DependentToPrincipal : foreignKey.PrincipalToDependent;
- var innerEntityReference = UnwrapEntityReference(innerSource.PendingSelector);
+ // Value known to be non-null
+ var innerEntityReference = UnwrapEntityReference(innerSource.PendingSelector)!;
if (navigation != null
&& entityReference.IncludePaths.TryGetValue(navigation, out var includeTree))
{
@@ -603,7 +610,10 @@ protected override Expression VisitNew(NewExpression newExpression)
return newExpression.Update(arguments);
}
- private bool ReconstructAnonymousType(Expression currentRoot, NewExpression newExpression, out Expression replacement)
+ private bool ReconstructAnonymousType(
+ Expression currentRoot,
+ NewExpression newExpression,
+ [CA.NotNullWhen(true)] out Expression? replacement)
{
replacement = null;
var changed = false;
@@ -676,7 +686,7 @@ private void VerifyNoCycles(IncludeTreeNode includeTreeNode)
}
}
- private Expression ExpandIncludesHelper(Expression root, EntityReference entityReference, INavigationBase previousNavigation)
+ private Expression ExpandIncludesHelper(Expression root, EntityReference entityReference, INavigationBase? previousNavigation)
{
var result = root;
var convertedRoot = root;
@@ -709,9 +719,8 @@ private Expression ExpandIncludesHelper(Expression root, EntityReference entityR
// Collection will expand it's includes when reducing the navigationExpansionExpression
if (!navigationBase.IsCollection)
{
- var innerEntityReference = UnwrapEntityReference(included);
-
- included = ExpandIncludesHelper(included, innerEntityReference, navigationBase);
+ // Value known to be non-null
+ included = ExpandIncludesHelper(included, UnwrapEntityReference(included)!, navigationBase);
}
else
{
@@ -723,7 +732,7 @@ private Expression ExpandIncludesHelper(Expression root, EntityReference entityR
&& subquery is MethodCallExpression subqueryMethodCallExpression
&& subqueryMethodCallExpression.Method.IsGenericMethod)
{
- EntityReference innerEntityReference = null;
+ EntityReference? innerEntityReference = null;
if (subqueryMethodCallExpression.Method.GetGenericMethodDefinition() == QueryableMethods.Where
&& subqueryMethodCallExpression.Arguments[0] is NavigationExpansionExpression navigationExpansionExpression)
{
@@ -1060,7 +1069,11 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return base.VisitMethodCall(methodCallExpression);
}
- private bool TryRemoveNavigationComparison(ExpressionType nodeType, Expression left, Expression right, out Expression result)
+ private bool TryRemoveNavigationComparison(
+ ExpressionType nodeType,
+ Expression left,
+ Expression right,
+ [CA.NotNullWhen(true)] out Expression? result)
{
result = null;
var leftNavigationData = ProcessNavigationPath(left) as NavigationDataExpression;
@@ -1075,16 +1088,17 @@ private bool TryRemoveNavigationComparison(ExpressionType nodeType, Expression l
if (left.IsNullConstantExpression()
|| right.IsNullConstantExpression())
{
- var nonNullNavigationData = left.IsNullConstantExpression()
- ? rightNavigationData
- : leftNavigationData;
+ NavigationDataExpression nonNullNavigationData = left.IsNullConstantExpression()
+ ? rightNavigationData!
+ : leftNavigationData!;
if (nonNullNavigationData.Navigation?.IsCollection == true)
{
_logger.PossibleUnintendedCollectionNavigationNullComparisonWarning(nonNullNavigationData.Navigation);
+ // Inner would be non-null when navigation is non-null
result = Expression.MakeBinary(
- nodeType, nonNullNavigationData.Inner.Current, Expression.Constant(null, nonNullNavigationData.Inner.Type));
+ nodeType, nonNullNavigationData.Inner!.Current, Expression.Constant(null, nonNullNavigationData.Inner.Type));
return true;
}
@@ -1097,8 +1111,8 @@ private bool TryRemoveNavigationComparison(ExpressionType nodeType, Expression l
if (leftNavigationData.Navigation == rightNavigationData.Navigation)
{
_logger.PossibleUnintendedReferenceComparisonWarning(leftNavigationData.Current, rightNavigationData.Current);
-
- result = Expression.MakeBinary(nodeType, leftNavigationData.Inner.Current, rightNavigationData.Inner.Current);
+ // Inner would be non-null when navigation is non-null
+ result = Expression.MakeBinary(nodeType, leftNavigationData.Inner!.Current, rightNavigationData.Inner!.Current);
}
else
{
@@ -1182,10 +1196,10 @@ public override Type Type
public override ExpressionType NodeType
=> ExpressionType.Extension;
- public INavigation Navigation { get; }
+ public INavigation? Navigation { get; }
public Expression Current { get; }
- public NavigationDataExpression Inner { get; }
- public IEntityType EntityType { get; }
+ public NavigationDataExpression? Inner { get; }
+ public IEntityType? EntityType { get; }
}
}
}
diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs
index f9afd57ca99..568b54dfa49 100644
--- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs
+++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs
@@ -9,6 +9,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public partial class NavigationExpandingExpressionVisitor
@@ -28,13 +30,14 @@ public EntityReference(IEntityType entityType)
public bool IsOptional { get; private set; }
public IncludeTreeNode IncludePaths { get; private set; }
- public IncludeTreeNode LastIncludeTreeNode { get; private set; }
+ public IncludeTreeNode? LastIncludeTreeNode { get; private set; }
public override ExpressionType NodeType
=> ExpressionType.Extension;
public override Type Type
- => EntityType.ClrType;
+ // No shadow entities at runtime
+ => EntityType.ClrType!;
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
@@ -83,21 +86,21 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
///
private sealed class IncludeTreeNode : Dictionary
{
- private EntityReference _entityReference;
+ private EntityReference? _entityReference;
public IncludeTreeNode(IEntityType entityType)
{
EntityType = entityType;
}
- public IncludeTreeNode(IEntityType entityType, EntityReference entityReference)
+ public IncludeTreeNode(IEntityType entityType, EntityReference? entityReference)
{
EntityType = entityType;
_entityReference = entityReference;
}
public IEntityType EntityType { get; }
- public LambdaExpression FilterExpression { get; private set; }
+ public LambdaExpression? FilterExpression { get; private set; }
public IncludeTreeNode AddNavigation(INavigationBase navigation)
{
@@ -106,22 +109,25 @@ public IncludeTreeNode AddNavigation(INavigationBase navigation)
return existingValue;
}
- IncludeTreeNode nodeToAdd = null;
+ IncludeTreeNode? nodeToAdd = null;
if (_entityReference != null)
{
if (navigation is INavigation concreteNavigation
&& _entityReference.ForeignKeyExpansionMap.TryGetValue(
(concreteNavigation.ForeignKey, concreteNavigation.IsOnDependent), out var expansion))
{
- nodeToAdd = UnwrapEntityReference(expansion).IncludePaths;
+ // Value known to be non-null
+ nodeToAdd = UnwrapEntityReference(expansion)!.IncludePaths;
}
else if (navigation is ISkipNavigation skipNavigation
&& _entityReference.ForeignKeyExpansionMap.TryGetValue(
(skipNavigation.ForeignKey, skipNavigation.IsOnDependent), out var firstExpansion)
- && UnwrapEntityReference(firstExpansion).ForeignKeyExpansionMap.TryGetValue(
+ // Value known to be non-null
+ && UnwrapEntityReference(firstExpansion)!.ForeignKeyExpansionMap.TryGetValue(
(skipNavigation.Inverse.ForeignKey, !skipNavigation.Inverse.IsOnDependent), out var secondExpansion))
{
- nodeToAdd = UnwrapEntityReference(secondExpansion).IncludePaths;
+ // Value known to be non-null
+ nodeToAdd = UnwrapEntityReference(secondExpansion)!.IncludePaths;
}
}
@@ -135,7 +141,7 @@ public IncludeTreeNode AddNavigation(INavigationBase navigation)
return this[navigation];
}
- public IncludeTreeNode Snapshot(EntityReference entityReference)
+ public IncludeTreeNode Snapshot(EntityReference? entityReference)
{
var result = new IncludeTreeNode(EntityType, entityReference) { FilterExpression = FilterExpression };
@@ -163,7 +169,7 @@ public void AssignEntityReference(EntityReference entityReference)
public void ApplyFilter(LambdaExpression filterExpression)
=> FilterExpression = filterExpression;
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj != null
&& (ReferenceEquals(this, obj)
|| obj is IncludeTreeNode includeTreeNode
@@ -203,7 +209,7 @@ private sealed class NavigationExpansionExpression : Expression, IPrintableExpre
private readonly string _parameterName;
- private NavigationTreeNode _currentTree;
+ private NavigationTreeNode? _currentTree;
public NavigationExpansionExpression(
Expression source,
@@ -220,11 +226,13 @@ public NavigationExpansionExpression(
public Expression Source { get; private set; }
public ParameterExpression CurrentParameter
- => CurrentTree.CurrentParameter;
+ // CurrentParameter would be non-null if CurrentTree is non-null
+ => CurrentTree.CurrentParameter!;
public NavigationTreeNode CurrentTree
{
- get => _currentTree;
+ // _currentTree is always non-null. Field is to override the setter to set parameter
+ get => _currentTree!;
private set
{
_currentTree = value;
@@ -233,7 +241,7 @@ private set
}
public Expression PendingSelector { get; private set; }
- public MethodInfo CardinalityReducingGenericMethodInfo { get; private set; }
+ public MethodInfo? CardinalityReducingGenericMethodInfo { get; private set; }
public Type SourceElementType
=> CurrentParameter.Type;
@@ -354,32 +362,25 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
///
private class NavigationTreeNode : Expression
{
- private NavigationTreeNode _parent;
+ private NavigationTreeNode? _parent;
- public NavigationTreeNode(NavigationTreeNode left, NavigationTreeNode right)
+ public NavigationTreeNode(NavigationTreeNode? left, NavigationTreeNode? right)
{
Left = left;
Right = right;
- if (left != null)
- {
- Left.Parent = this;
- Right.Parent = this;
- }
- }
-
- public NavigationTreeNode Parent
- {
- get => _parent;
- private set
+ if (left != null
+ && right != null)
{
- _parent = value;
- CurrentParameter = null;
+ left._parent = this;
+ left.CurrentParameter = null;
+ right._parent = this;
+ right.CurrentParameter = null;
}
}
- public NavigationTreeNode Left { get; }
- public NavigationTreeNode Right { get; }
- public ParameterExpression CurrentParameter { get; private set; }
+ public NavigationTreeNode? Left { get; }
+ public NavigationTreeNode? Right { get; }
+ public ParameterExpression? CurrentParameter { get; private set; }
public void SetParameter(string parameterName)
=> CurrentParameter = Parameter(Type, parameterName);
@@ -388,17 +389,19 @@ public override ExpressionType NodeType
=> ExpressionType.Extension;
public override Type Type
- => TransparentIdentifierFactory.Create(Left.Type, Right.Type);
+ // Left/Right could be null for NavigationTreeExpression (derived type) but it overrides this property.
+ => TransparentIdentifierFactory.Create(Left!.Type, Right!.Type);
public Expression GetExpression()
{
- if (Parent == null)
+ if (_parent == null)
{
- return CurrentParameter;
+ // If parent is null and CurrentParameter is non-null & vice-versa
+ return CurrentParameter!;
}
- var parentExperssion = Parent.GetExpression();
- return Parent.Left == this
+ var parentExperssion = _parent.GetExpression();
+ return _parent.Left == this
? MakeMemberAccess(parentExperssion, parentExperssion.Type.GetMember("Outer")[0])
: MakeMemberAccess(parentExperssion, parentExperssion.Type.GetMember("Inner")[0]);
}
diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
index c8199807251..190661641d3 100644
--- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
@@ -14,6 +14,8 @@
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
@@ -97,10 +99,9 @@ public NavigationExpandingExpressionVisitor(
parameterize: false,
generateContextAccessors: true);
- if (!_queryCompilationContext.IgnoreAutoIncludes)
- {
- _nonCyclicAutoIncludeEntityTypes = new HashSet();
- }
+ // TODO: Use MemberNotNullWhen
+ // Value won't be accessed when condition is not met.
+ _nonCyclicAutoIncludeEntityTypes = !_queryCompilationContext.IgnoreAutoIncludes ? new HashSet() : null!;
}
///
@@ -605,7 +606,7 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression)
private Expression ProcessAllAnyCountLongCount(
NavigationExpansionExpression source,
MethodInfo genericMethod,
- LambdaExpression predicate)
+ LambdaExpression? predicate)
{
if (predicate != null)
{
@@ -618,7 +619,7 @@ private Expression ProcessAllAnyCountLongCount(
return Expression.Call(genericMethod.MakeGenericMethod(source.SourceElementType), source.Source);
}
- private Expression ProcessAverageMaxMinSum(NavigationExpansionExpression source, MethodInfo method, LambdaExpression selector)
+ private Expression ProcessAverageMaxMinSum(NavigationExpansionExpression source, MethodInfo method, LambdaExpression? selector)
{
if (selector != null)
{
@@ -761,7 +762,7 @@ private NavigationExpansionExpression ProcessSkipTake(
private NavigationExpansionExpression ProcessFirstSingleLastOrDefault(
NavigationExpansionExpression source,
MethodInfo genericMethod,
- LambdaExpression predicate,
+ LambdaExpression? predicate,
Type returnType)
{
if (predicate != null)
@@ -783,8 +784,8 @@ private NavigationExpansionExpression ProcessFirstSingleLastOrDefault(
private NavigationExpansionExpression ProcessGroupBy(
NavigationExpansionExpression source,
LambdaExpression keySelector,
- LambdaExpression elementSelector,
- LambdaExpression resultSelector)
+ LambdaExpression? elementSelector,
+ LambdaExpression? resultSelector)
{
var keySelectorBody = ExpandNavigationsForSource(source, RemapLambdaExpression(source, keySelector));
// Need to generate lambda after processing element/result selector
@@ -867,7 +868,8 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi
else
{
var currentIncludeTreeNode = thenInclude
- ? entityReference.LastIncludeTreeNode
+ // LastIncludeTreeNode would be non-null for ThenInclude
+ ? entityReference.LastIncludeTreeNode!
: entityReference.IncludePaths;
var includeLambda = expression.UnwrapLambdaFromQuote();
@@ -895,7 +897,7 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi
throw new InvalidOperationException(CoreStrings.IncludeOnNonEntity(expression.Print()));
- static (Expression result, LambdaExpression filterExpression) ExtractIncludeFilter(
+ static (Expression result, LambdaExpression? filterExpression) ExtractIncludeFilter(
Expression currentExpression,
Expression includeExpression)
{
@@ -1124,7 +1126,7 @@ private NavigationExpansionExpression ProcessSelect(NavigationExpansionExpressio
private NavigationExpansionExpression ProcessSelectMany(
NavigationExpansionExpression source,
LambdaExpression collectionSelector,
- LambdaExpression resultSelector)
+ LambdaExpression? resultSelector)
{
var collectionSelectorBody = ExpandNavigationsForSource(source, RemapLambdaExpression(source, collectionSelector));
if (collectionSelectorBody is MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression)
@@ -1476,7 +1478,7 @@ private MethodCallExpression ConvertToEnumerable(MethodInfo queryableMethod, IEn
{
var genericTypeArguments = queryableMethod.IsGenericMethod
? queryableMethod.GetGenericArguments()
- : null;
+ : Array.Empty();
var enumerableArguments = arguments.Select(
arg => arg is UnaryExpression unaryExpression
&& unaryExpression.NodeType == ExpressionType.Quote
@@ -1658,9 +1660,12 @@ private static IEnumerable FindNavigations(IEntityType entityTy
else
{
foreach (var derivedSkipNavigation in entityType.GetDerivedTypes()
- .Select(et => et.FindDeclaredSkipNavigation(navigationName)).Where(n => n != null))
+ .Select(et => et.FindDeclaredSkipNavigation(navigationName)))
{
- yield return derivedSkipNavigation;
+ if (derivedSkipNavigation != null)
+ {
+ yield return derivedSkipNavigation;
+ }
}
}
}
@@ -1860,7 +1865,7 @@ private Expression SnapshotExpression(Expression selector)
}
}
- private static EntityReference UnwrapEntityReference(Expression expression)
+ private static EntityReference? UnwrapEntityReference(Expression expression)
{
switch (expression)
{
diff --git a/src/EFCore/Query/Internal/NullAsyncQueryProvider.cs b/src/EFCore/Query/Internal/NullAsyncQueryProvider.cs
index 5669a08ed23..df8ced66055 100644
--- a/src/EFCore/Query/Internal/NullAsyncQueryProvider.cs
+++ b/src/EFCore/Query/Internal/NullAsyncQueryProvider.cs
@@ -7,6 +7,8 @@
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs b/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
index 5eb79edc4c2..afdc6662bbc 100644
--- a/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
@@ -4,6 +4,9 @@
using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
@@ -73,7 +76,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
return base.VisitConditional(conditionalExpression);
}
- private Expression TryOptimizeConditionalEquality(Expression expression)
+ private Expression? TryOptimizeConditionalEquality(Expression expression)
{
// Simplify (a ? b : null) == null => !a || b == null
// Simplify (a ? null : b) == null => a || b == null
@@ -89,7 +92,7 @@ private Expression TryOptimizeConditionalEquality(Expression expression)
}
else
{
- conditionalExpression = binaryExpression.Right as ConditionalExpression;
+ conditionalExpression = (ConditionalExpression)binaryExpression.Right;
comparedExpression = binaryExpression.Left;
}
@@ -126,7 +129,8 @@ public bool Verify(Expression caller, Expression result)
return _nullSafeAccesses.Contains(result);
}
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
=> expression == null || _nullSafeAccesses.Contains(expression)
? expression
: base.Visit(expression);
diff --git a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
index bedbb7b1b3d..76f2801bd9f 100644
--- a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
@@ -11,6 +11,9 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
@@ -35,7 +38,7 @@ private readonly Dictionary _evaluatedValues
= new Dictionary(ExpressionEqualityComparer.Instance);
private IDictionary _evaluatableExpressions;
- private IQueryProvider _currentQueryProvider;
+ private IQueryProvider? _currentQueryProvider;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -58,10 +61,13 @@ public ParameterExtractingExpressionVisitor(
_logger = logger;
_parameterize = parameterize;
_generateContextAccessors = generateContextAccessors;
- if (_generateContextAccessors)
- {
- _contextParameterReplacingExpressionVisitor = new ContextParameterReplacingExpressionVisitor(contextType);
- }
+ // The entry method will take care of populating this field always. So accesses should be safe.
+ _evaluatableExpressions = null!;
+ // TODO: Use MemberNotNullWhen
+ // Value won't be accessed when condition is not met.
+ _contextParameterReplacingExpressionVisitor = _generateContextAccessors
+ ? new ContextParameterReplacingExpressionVisitor(contextType)
+ : null!;
}
///
@@ -92,7 +98,8 @@ public virtual Expression ExtractParameters([NotNull] Expression expression)
/// 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 Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression == null)
{
@@ -215,7 +222,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
}
}
- private Expression TryGetConstantValue(Expression expression)
+ private Expression? TryGetConstantValue(Expression expression)
{
if (_evaluatableExpressions.ContainsKey(expression))
{
@@ -367,7 +374,8 @@ private static Expression RemoveConvert(Expression expression)
return expression;
}
- private object GetValue(Expression expression, out string parameterName)
+ [return: CA.NotNullIfNotNull("expression")]
+ private object? GetValue(Expression? expression, out string? parameterName)
{
parameterName = null;
@@ -473,6 +481,8 @@ public EvaluatableExpressionFindingExpressionVisitor(
_evaluatableExpressionFilter = evaluatableExpressionFilter;
_model = model;
_parameterize = parameterize;
+ // The entry method will take care of populating this field always. So accesses should be safe.
+ _evaluatableExpressions = null!;
}
public IDictionary Find(Expression expression)
diff --git a/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs b/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs
index 939f07d5c52..109b3a34f14 100644
--- a/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs
+++ b/src/EFCore/Query/Internal/QueryCompilationContextFactory.cs
@@ -5,6 +5,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/QueryCompiler.cs b/src/EFCore/Query/Internal/QueryCompiler.cs
index 258272cb165..6b9715792cc 100644
--- a/src/EFCore/Query/Internal/QueryCompiler.cs
+++ b/src/EFCore/Query/Internal/QueryCompiler.cs
@@ -12,6 +12,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/QueryDebugView.cs b/src/EFCore/Query/Internal/QueryDebugView.cs
index fd4630a655a..30b1ebb0f31 100644
--- a/src/EFCore/Query/Internal/QueryDebugView.cs
+++ b/src/EFCore/Query/Internal/QueryDebugView.cs
@@ -5,6 +5,8 @@
using System.Diagnostics;
using JetBrains.Annotations;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
index 8a0d88758a6..5c9b8dcb595 100644
--- a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
@@ -6,6 +6,9 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
@@ -193,7 +196,11 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression)
return base.VisitUnary(unaryExpression);
}
- private bool TryExtractEqualityOperands(Expression expression, out Expression left, out Expression right, out bool negated)
+ private bool TryExtractEqualityOperands(
+ Expression expression,
+ [CA.NotNullWhen(true)] out Expression? left,
+ [CA.NotNullWhen(true)] out Expression? right,
+ out bool negated)
{
(left, right, negated) = (default, default, default);
@@ -223,14 +230,18 @@ private bool TryExtractEqualityOperands(Expression expression, out Expression le
&& methodCallExpression.Object.Type == methodCallExpression.Arguments[0].Type)
{
(left, right) = (methodCallExpression.Object, methodCallExpression.Arguments[0]);
+
+ return true;
}
else if (methodCallExpression.Arguments.Count == 2
&& methodCallExpression.Arguments[0].Type == methodCallExpression.Arguments[1].Type)
{
(left, right) = (methodCallExpression.Arguments[0], methodCallExpression.Arguments[1]);
+
+ return true;
}
- return true;
+ return false;
}
case UnaryExpression unaryExpression
@@ -245,7 +256,7 @@ when unaryExpression.IsLogicalNot():
return false;
}
- private Expression TryOptimizeMemberAccessOverConditional(Expression expression)
+ private Expression? TryOptimizeMemberAccessOverConditional(Expression expression)
{
// Simplify (a != null ? new { Member = b, ... } : null).Member
// to a != null ? b : null
diff --git a/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs b/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs
index 41e8fb76882..c03bfda0f3b 100644
--- a/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs
+++ b/src/EFCore/Query/Internal/QueryTranslationPostprocessorFactory.cs
@@ -5,6 +5,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs b/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs
index d71bb40d6c2..3c8fb35d9d1 100644
--- a/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs
+++ b/src/EFCore/Query/Internal/QueryTranslationPreprocessorFactory.cs
@@ -5,6 +5,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
index 2025e7ce373..42e458f962a 100644
--- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
@@ -13,6 +13,8 @@
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
@@ -61,7 +63,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return expression;
}
- Expression visitedExpression = null;
+ Expression? visitedExpression = null;
if (method.DeclaringType == typeof(Enumerable))
{
visitedExpression = TryConvertEnumerableToQueryable(methodCallExpression);
@@ -173,7 +175,7 @@ private void VerifyReturnType(Expression expression, ParameterExpression lambdaP
}
}
- private Expression ExtractQueryMetadata(MethodCallExpression methodCallExpression)
+ private Expression? ExtractQueryMetadata(MethodCallExpression methodCallExpression)
{
// We visit innerQueryable first so that we can get information in the same order operators are applied.
var genericMethodDefinition = methodCallExpression.Method.GetGenericMethodDefinition();
@@ -251,7 +253,7 @@ private Expression TryConvertEnumerableToQueryable(MethodCallExpression methodCa
var enumerableMethod = methodCallExpression.Method;
var enumerableParameters = enumerableMethod.GetParameters();
- Type[] genericTypeArguments = null;
+ Type[] genericTypeArguments = Array.Empty();
if (enumerableMethod.Name == nameof(Enumerable.Min)
|| enumerableMethod.Name == nameof(Enumerable.Max))
{
@@ -633,7 +635,7 @@ private sealed class SelectManyVerifyingExpressionVisitor : ExpressionVisitor
private readonly List _allowedParameters = new List();
private readonly ISet _allowedMethods = new HashSet { nameof(Queryable.Where), nameof(Queryable.AsQueryable) };
- private ParameterExpression _rootParameter;
+ private ParameterExpression? _rootParameter;
private int _rootParameterCount;
private bool _correlated;
diff --git a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
index 4ec711c9f81..9065b1ec957 100644
--- a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
@@ -10,6 +10,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
///
diff --git a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs
index 9e2b910296e..442c9025aa2 100644
--- a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs
+++ b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs
@@ -7,6 +7,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/ProjectionBindingExpression.cs b/src/EFCore/Query/ProjectionBindingExpression.cs
index 669f5d07555..94a5fab35d9 100644
--- a/src/EFCore/Query/ProjectionBindingExpression.cs
+++ b/src/EFCore/Query/ProjectionBindingExpression.cs
@@ -9,6 +9,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -87,7 +89,7 @@ public ProjectionBindingExpression(
///
/// The projection member to bind if binding is via projection member.
///
- public virtual ProjectionMember ProjectionMember { get; }
+ public virtual ProjectionMember? ProjectionMember { get; }
///
/// The projection member to bind if binding is via projection index.
@@ -97,7 +99,7 @@ public ProjectionBindingExpression(
///
/// The projection member to bind if binding is via index map for a value buffer.
///
- public virtual IDictionary IndexMap { get; }
+ public virtual IDictionary? IndexMap { get; }
///
public override Type Type { get; }
@@ -128,7 +130,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
{
expressionPrinter.Append(Index.ToString());
}
- else
+ else if (IndexMap != null)
{
using (expressionPrinter.Indent())
{
@@ -141,7 +143,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
}
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj != null
&& (ReferenceEquals(this, obj)
|| obj is ProjectionBindingExpression projectionBindingExpression
diff --git a/src/EFCore/Query/ProjectionMember.cs b/src/EFCore/Query/ProjectionMember.cs
index 6d520c703a7..d2a130ac248 100644
--- a/src/EFCore/Query/ProjectionMember.cs
+++ b/src/EFCore/Query/ProjectionMember.cs
@@ -9,6 +9,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -95,7 +97,7 @@ public override int GetHashCode()
}
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj != null
&& (obj is ProjectionMember projectionMember
&& Equals(projectionMember));
diff --git a/src/EFCore/Query/QueryCompilationContext.cs b/src/EFCore/Query/QueryCompilationContext.cs
index 0f1723eb0ff..ba57ca4542a 100644
--- a/src/EFCore/Query/QueryCompilationContext.cs
+++ b/src/EFCore/Query/QueryCompilationContext.cs
@@ -12,6 +12,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -54,7 +56,7 @@ public class QueryCompilationContext
private readonly ExpressionPrinter _expressionPrinter;
- private Dictionary _runtimeParameters;
+ private Dictionary? _runtimeParameters;
///
/// Creates a new instance of the class.
diff --git a/src/EFCore/Query/QueryCompilationContextDependencies.cs b/src/EFCore/Query/QueryCompilationContextDependencies.cs
index e2b466c47b1..a5654034986 100644
--- a/src/EFCore/Query/QueryCompilationContextDependencies.cs
+++ b/src/EFCore/Query/QueryCompilationContextDependencies.cs
@@ -10,6 +10,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryContext.cs b/src/EFCore/Query/QueryContext.cs
index dbe61d7d497..9568ebfe42b 100644
--- a/src/EFCore/Query/QueryContext.cs
+++ b/src/EFCore/Query/QueryContext.cs
@@ -14,6 +14,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -28,7 +30,7 @@ namespace Microsoft.EntityFrameworkCore.Query
public abstract class QueryContext : IParameterValues
{
private readonly IDictionary _parameterValues = new Dictionary();
- private IStateManager _stateManager;
+ private IStateManager? _stateManager;
///
///
@@ -69,7 +71,8 @@ public virtual void SetNavigationIsLoaded([NotNull] object entity, [NotNull] INa
Check.NotNull(entity, nameof(entity));
Check.NotNull(navigation, nameof(navigation));
- _stateManager.TryGetEntry(entity).SetIsLoaded(navigation);
+ // InitializeStateManager will populate the field before calling here
+ _stateManager!.TryGetEntry(entity).SetIsLoaded(navigation);
}
///
@@ -154,7 +157,8 @@ public virtual InternalEntityEntry TryGetEntry(
[NotNull] object[] keyValues,
bool throwOnNullKey,
out bool hasNullKey)
- => _stateManager.TryGetEntry(key, keyValues, throwOnNullKey, out hasNullKey);
+ // InitializeStateManager will populate the field before calling here
+ => _stateManager!.TryGetEntry(key, keyValues, throwOnNullKey, out hasNullKey);
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -167,6 +171,7 @@ public virtual InternalEntityEntry StartTracking(
[NotNull] IEntityType entityType,
[NotNull] object entity,
ValueBuffer valueBuffer)
- => _stateManager.StartTrackingFromQuery(entityType, entity, valueBuffer);
+ // InitializeStateManager will populate the field before calling here
+ => _stateManager!.StartTrackingFromQuery(entityType, entity, valueBuffer);
}
}
diff --git a/src/EFCore/Query/QueryContextDependencies.cs b/src/EFCore/Query/QueryContextDependencies.cs
index b666d156474..9181d6c5ab4 100644
--- a/src/EFCore/Query/QueryContextDependencies.cs
+++ b/src/EFCore/Query/QueryContextDependencies.cs
@@ -12,6 +12,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryRootExpression.cs b/src/EFCore/Query/QueryRootExpression.cs
index f180cf39bcb..00fbf6201fb 100644
--- a/src/EFCore/Query/QueryRootExpression.cs
+++ b/src/EFCore/Query/QueryRootExpression.cs
@@ -9,6 +9,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -53,7 +55,7 @@ public QueryRootExpression([NotNull] IEntityType entityType)
///
/// The query provider associated with this query root.
///
- public virtual IAsyncQueryProvider QueryProvider { get; }
+ public virtual IAsyncQueryProvider? QueryProvider { get; }
///
/// The entity type reprenseted by this query root.
@@ -105,7 +107,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
=> Print(expressionPrinter);
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj != null
&& (ReferenceEquals(this, obj)
|| obj is QueryRootExpression queryRootExpression
diff --git a/src/EFCore/Query/QueryTranslationPostprocessor.cs b/src/EFCore/Query/QueryTranslationPostprocessor.cs
index dbe159e6522..f0d98eb6b71 100644
--- a/src/EFCore/Query/QueryTranslationPostprocessor.cs
+++ b/src/EFCore/Query/QueryTranslationPostprocessor.cs
@@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryTranslationPostprocessorDependencies.cs b/src/EFCore/Query/QueryTranslationPostprocessorDependencies.cs
index 639307af0e2..fa7d75b264b 100644
--- a/src/EFCore/Query/QueryTranslationPostprocessorDependencies.cs
+++ b/src/EFCore/Query/QueryTranslationPostprocessorDependencies.cs
@@ -4,6 +4,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryTranslationPreprocessor.cs b/src/EFCore/Query/QueryTranslationPreprocessor.cs
index d819ec8f3ac..b0e5cafba00 100644
--- a/src/EFCore/Query/QueryTranslationPreprocessor.cs
+++ b/src/EFCore/Query/QueryTranslationPreprocessor.cs
@@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryTranslationPreprocessorDependencies.cs b/src/EFCore/Query/QueryTranslationPreprocessorDependencies.cs
index a5a06e67c3e..55f071b1054 100644
--- a/src/EFCore/Query/QueryTranslationPreprocessorDependencies.cs
+++ b/src/EFCore/Query/QueryTranslationPreprocessorDependencies.cs
@@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
index 088298656af..12c82aabae7 100644
--- a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
@@ -13,6 +13,8 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -57,7 +59,7 @@ protected QueryableMethodTranslatingExpressionVisitor(
///
/// Detailed information about errors encountered during translation.
///
- public virtual string TranslationErrorDetails { get; private set; }
+ public virtual string? TranslationErrorDetails { get; private set; }
///
/// Adds detailed information about errors encountered during translation.
@@ -96,7 +98,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
}
///
- protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
+ protected override Expression? VisitMethodCall(MethodCallExpression methodCallExpression)
{
Check.NotNull(methodCallExpression, nameof(methodCallExpression));
@@ -493,7 +495,7 @@ LambdaExpression GetLambdaExpressionFromArgument(int argumentIndex)
}
return _subquery
- ? (Expression)null
+ ? (Expression?)null
: throw new InvalidOperationException(CoreStrings.TranslationFailed(methodCallExpression.Print()));
}
@@ -598,7 +600,8 @@ protected override Expression VisitExtension(Expression extensionExpression)
return extensionExpression is ProjectionBindingExpression projectionBindingExpression
? new ProjectionBindingExpression(
_queryExpression,
- projectionBindingExpression.ProjectionMember.Prepend(_memberShift),
+ // ProjectionMember would be non-null here as we are shifting members
+ projectionBindingExpression.ProjectionMember!.Prepend(_memberShift),
projectionBindingExpression.Type)
: base.VisitExtension(extensionExpression);
}
@@ -629,7 +632,7 @@ private static Expression AccessInnerTransparentField(
///
/// The subquery expression to translate.
/// The translation of the given subquery.
- public virtual ShapedQueryExpression TranslateSubquery([NotNull] Expression expression)
+ public virtual ShapedQueryExpression? TranslateSubquery([NotNull] Expression expression)
{
Check.NotNull(expression, nameof(expression));
@@ -680,7 +683,7 @@ public virtual ShapedQueryExpression TranslateSubquery([NotNull] Expression expr
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateAny(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate);
+ [CanBeNull] LambdaExpression? predicate);
///
/// Translates method and other overloads over the given source.
@@ -691,7 +694,7 @@ protected abstract ShapedQueryExpression TranslateAny(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateAverage(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression selector,
+ [CanBeNull] LambdaExpression? selector,
[NotNull] Type resultType);
///
@@ -728,7 +731,7 @@ protected abstract ShapedQueryExpression TranslateConcat(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateCount(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate);
+ [CanBeNull] LambdaExpression? predicate);
///
/// Translates method and other overloads over the given source.
@@ -738,7 +741,7 @@ protected abstract ShapedQueryExpression TranslateCount(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateDefaultIfEmpty(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] Expression defaultValue);
+ [CanBeNull] Expression? defaultValue);
///
/// Translates method over the given source.
@@ -781,7 +784,7 @@ protected abstract ShapedQueryExpression TranslateExcept(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateFirstOrDefault(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate,
+ [CanBeNull] LambdaExpression? predicate,
[NotNull] Type returnType,
bool returnDefault);
@@ -797,8 +800,8 @@ protected abstract ShapedQueryExpression TranslateFirstOrDefault(
protected abstract ShapedQueryExpression TranslateGroupBy(
[NotNull] ShapedQueryExpression source,
[NotNull] LambdaExpression keySelector,
- [CanBeNull] LambdaExpression elementSelector,
- [CanBeNull] LambdaExpression resultSelector);
+ [CanBeNull] LambdaExpression? elementSelector,
+ [CanBeNull] LambdaExpression? resultSelector);
///
/// Translates
@@ -844,8 +847,8 @@ protected abstract ShapedQueryExpression TranslateIntersect(
protected abstract ShapedQueryExpression TranslateJoin(
[NotNull] ShapedQueryExpression outer,
[NotNull] ShapedQueryExpression inner,
- [CanBeNull] LambdaExpression outerKeySelector,
- [CanBeNull] LambdaExpression innerKeySelector,
+ [NotNull] LambdaExpression outerKeySelector,
+ [NotNull] LambdaExpression innerKeySelector,
[NotNull] LambdaExpression resultSelector);
///
@@ -866,8 +869,8 @@ protected abstract ShapedQueryExpression TranslateJoin(
protected abstract ShapedQueryExpression TranslateLeftJoin(
[NotNull] ShapedQueryExpression outer,
[NotNull] ShapedQueryExpression inner,
- [CanBeNull] LambdaExpression outerKeySelector,
- [CanBeNull] LambdaExpression innerKeySelector,
+ [NotNull] LambdaExpression outerKeySelector,
+ [NotNull] LambdaExpression innerKeySelector,
[NotNull] LambdaExpression resultSelector);
///
@@ -881,7 +884,7 @@ protected abstract ShapedQueryExpression TranslateLeftJoin(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateLastOrDefault(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate,
+ [CanBeNull] LambdaExpression? predicate,
[NotNull] Type returnType,
bool returnDefault);
@@ -893,7 +896,7 @@ protected abstract ShapedQueryExpression TranslateLastOrDefault(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateLongCount(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate);
+ [CanBeNull] LambdaExpression? predicate);
///
/// Translates method and other overloads over the given source.
@@ -904,7 +907,7 @@ protected abstract ShapedQueryExpression TranslateLongCount(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateMax(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression selector,
+ [CanBeNull] LambdaExpression? selector,
[NotNull] Type resultType);
///
@@ -916,7 +919,7 @@ protected abstract ShapedQueryExpression TranslateMax(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateMin(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression selector,
+ [CanBeNull] LambdaExpression? selector,
[NotNull] Type resultType);
///
@@ -997,7 +1000,7 @@ protected abstract ShapedQueryExpression TranslateSelectMany(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateSingleOrDefault(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression predicate,
+ [CanBeNull] LambdaExpression? predicate,
[NotNull] Type returnType,
bool returnDefault);
@@ -1031,7 +1034,7 @@ protected abstract ShapedQueryExpression TranslateSkipWhile(
/// The shaped query after translation.
protected abstract ShapedQueryExpression TranslateSum(
[NotNull] ShapedQueryExpression source,
- [CanBeNull] LambdaExpression selector,
+ [CanBeNull] LambdaExpression? selector,
[NotNull] Type resultType);
///
diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs
index ed92c797b8f..8cc4a416dca 100644
--- a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs
+++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs
@@ -4,6 +4,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/QueryableMethods.cs b/src/EFCore/Query/QueryableMethods.cs
index 96a0bcf81a5..008a069ce1d 100644
--- a/src/EFCore/Query/QueryableMethods.cs
+++ b/src/EFCore/Query/QueryableMethods.cs
@@ -9,6 +9,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -43,7 +45,7 @@ public static class QueryableMethods
///
/// The for
- ///
+ ///
///
public static MethodInfo AnyWithPredicate { get; }
@@ -79,7 +81,7 @@ public static class QueryableMethods
///
/// The for
- ///
+ ///
///
public static MethodInfo CountWithPredicate { get; }
diff --git a/src/EFCore/Query/ReplacingExpressionVisitor.cs b/src/EFCore/Query/ReplacingExpressionVisitor.cs
index 4e0ede84eb6..d8c2d281ff1 100644
--- a/src/EFCore/Query/ReplacingExpressionVisitor.cs
+++ b/src/EFCore/Query/ReplacingExpressionVisitor.cs
@@ -8,6 +8,9 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Microsoft.EntityFrameworkCore.Query
{
@@ -56,7 +59,8 @@ public ReplacingExpressionVisitor([NotNull] IReadOnlyList originals,
}
///
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression == null
|| expression is ShapedQueryExpression
diff --git a/src/EFCore/Query/ResultCardinality.cs b/src/EFCore/Query/ResultCardinality.cs
index 451299c13a2..f22d7c78398 100644
--- a/src/EFCore/Query/ResultCardinality.cs
+++ b/src/EFCore/Query/ResultCardinality.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.Query
{
///
diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
index f132f729cfc..e277e16c3f7 100644
--- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
@@ -17,6 +17,8 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
@@ -41,7 +43,7 @@ public abstract class ShapedQueryCompilingExpressionVisitor : ExpressionVisitor
private static readonly PropertyInfo _cancellationTokenMemberInfo
= typeof(QueryContext).GetProperty(nameof(QueryContext.CancellationToken));
- private readonly Expression _cancellationTokenParameter;
+ private readonly Expression? _cancellationTokenParameter;
private readonly EntityMaterializerInjectingExpressionVisitor _entityMaterializerInjectingExpressionVisitor;
private readonly ConstantVerifyingExpressionVisitor _constantVerifyingExpressionVisitor;
@@ -161,7 +163,9 @@ private static async Task SingleOrDefaultAsync(
await using var enumerator = asyncEnumerable.GetAsyncEnumerator(cancellationToken);
if (!(await enumerator.MoveNextAsync().ConfigureAwait(false)))
{
- return default;
+ // TODO: Convert return to Task when changing to C# 9
+ // There is currently no way to specify that this method can return Task where TSource is not constrainted.
+ return default!;
}
var result = enumerator.Current;
@@ -275,7 +279,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
: base.VisitExtension(extensionExpression);
}
- private static Expression RemoveConvert(Expression expression)
+ private static Expression? RemoveConvert(Expression? expression)
{
while (expression != null
&& (expression.NodeType == ExpressionType.Convert
@@ -343,7 +347,7 @@ public Expression Inject(Expression expression)
}
}
- bool ContainsOwner(IEntityType owner)
+ bool ContainsOwner(IEntityType? owner)
=> owner != null && (_visitedEntityTypes.Contains(owner) || ContainsOwner(owner.BaseType));
}
@@ -476,7 +480,7 @@ private Expression MaterializeEntity(
ParameterExpression materializationContextVariable,
ParameterExpression concreteEntityTypeVariable,
ParameterExpression instanceVariable,
- ParameterExpression entryVariable)
+ ParameterExpression? entryVariable)
{
var entityType = entityShaperExpression.EntityType;
@@ -492,7 +496,8 @@ private Expression MaterializeEntity(
shadowValuesVariable,
Expression.Constant(ValueBuffer.Empty)));
- var returnType = entityType.ClrType;
+ // No shadow entities at runtime
+ var returnType = entityType.ClrType!;
Expression materializationExpression;
var valueBufferExpression = Expression.Call(materializationContextVariable, MaterializationContext.GetValueBufferMethod);
var expressionContext = (returnType, materializationContextVariable, concreteEntityTypeVariable, shadowValuesVariable);
diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs
index 5c9f248d7bc..1217614aeda 100644
--- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs
+++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs
@@ -8,6 +8,8 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/ShapedQueryExpression.cs b/src/EFCore/Query/ShapedQueryExpression.cs
index 84b9545fc58..c981cba087f 100644
--- a/src/EFCore/Query/ShapedQueryExpression.cs
+++ b/src/EFCore/Query/ShapedQueryExpression.cs
@@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/EFCore/Query/TransparentIdentifierFactory.cs b/src/EFCore/Query/TransparentIdentifierFactory.cs
index 9f30e743638..2e98f2c272d 100644
--- a/src/EFCore/Query/TransparentIdentifierFactory.cs
+++ b/src/EFCore/Query/TransparentIdentifierFactory.cs
@@ -5,6 +5,8 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+#nullable enable
+
namespace Microsoft.EntityFrameworkCore.Query
{
///
diff --git a/src/Shared/Check.cs b/src/Shared/Check.cs
index d06aa69dfdb..0a3ab5dc2da 100644
--- a/src/Shared/Check.cs
+++ b/src/Shared/Check.cs
@@ -112,7 +112,7 @@ public static IReadOnlyList HasNoEmptyElements(
}
[Conditional("DEBUG")]
- public static void DebugAssert([CA.DoesNotReturnIfAttribute(false)] bool condition, string message)
+ public static void DebugAssert([CA.DoesNotReturnIf(false)] bool condition, string message)
{
if (!condition)
{
diff --git a/src/Shared/NonCapturingLazyInitializer.cs b/src/Shared/NonCapturingLazyInitializer.cs
index 749d0d6ed8b..cb38ffb5a01 100644
--- a/src/Shared/NonCapturingLazyInitializer.cs
+++ b/src/Shared/NonCapturingLazyInitializer.cs
@@ -16,7 +16,7 @@ internal static class NonCapturingLazyInitializer
{
public static TValue EnsureInitialized(
[CanBeNull, CA.NotNull] ref TValue? target,
- [CanBeNull] TParam param,
+ [NotNull] TParam param,
[NotNull] Func valueFactory)
where TValue : class
{
@@ -34,8 +34,8 @@ public static TValue EnsureInitialized(
public static TValue EnsureInitialized(
[CanBeNull, CA.NotNull] ref TValue? target,
- [CanBeNull] TParam1 param1,
- [CanBeNull] TParam2 param2,
+ [NotNull] TParam1 param1,
+ [NotNull] TParam2 param2,
[NotNull] Func valueFactory)
where TValue : class
{
@@ -48,7 +48,7 @@ public static TValue EnsureInitialized(
Interlocked.CompareExchange(ref target, valueFactory(param1, param2), null);
- return target!;
+ return target;
}
public static TValue EnsureInitialized(
@@ -65,27 +65,28 @@ public static TValue EnsureInitialized(
Interlocked.CompareExchange(ref target, value, null);
- return target!;
+ return target;
}
public static TValue EnsureInitialized(
[CanBeNull, CA.NotNull] ref TValue? target,
- [CanBeNull] TParam param,
+ [NotNull] TParam param,
[NotNull] Action valueFactory)
where TValue : class
{
- if (Volatile.Read(ref target) != null)
+ var tmp = Volatile.Read(ref target);
+ if (tmp != null)
{
Check.DebugAssert(target != null, $"target was null in {nameof(EnsureInitialized)} after check");
- return target!;
+ return tmp;
}
valueFactory(param);
- var tmp = Volatile.Read(ref target);
- Check.DebugAssert(target != null && tmp != null,
+ var tmp2 = Volatile.Read(ref target);
+ Check.DebugAssert(target != null && tmp2 != null,
$"{nameof(valueFactory)} did not initialize {nameof(target)} in {nameof(EnsureInitialized)}");
- return tmp;
+ return tmp2;
}
}
}
diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
index c0d21dc31c0..6393ea98f40 100644
--- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
+++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
@@ -1547,7 +1547,7 @@ public virtual void Shared_columns_are_stored_in_the_snapshot()
builder.Entity(b =>
{
b.ToTable("EntityWithProperties");
- b.Property(e => e.AlternateId).HasColumnName("AlternateId");
+ b.Property(e => e.AlternateId).HasColumnName("AlternateId");
b.HasOne(e => e.EntityWithOneProperty).WithOne(e => e.EntityWithTwoProperties)
.HasForeignKey(e => e.Id);
});
diff --git a/test/EFCore.Relational.Tests/RelationalEventIdTest.cs b/test/EFCore.Relational.Tests/RelationalEventIdTest.cs
index ab80a7fc823..de5a222b310 100644
--- a/test/EFCore.Relational.Tests/RelationalEventIdTest.cs
+++ b/test/EFCore.Relational.Tests/RelationalEventIdTest.cs
@@ -43,7 +43,7 @@ public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled()
var property = entityType.AddProperty("A", typeof(int), ConfigurationSource.Convention, ConfigurationSource.Convention);
var key = entityType.AddKey(property, ConfigurationSource.Convention);
var foreignKey = new ForeignKey(new List { property }, key, entityType, entityType, ConfigurationSource.Convention);
- var index = new Metadata.Internal.Index(new List { property }, "IndexName", entityType, ConfigurationSource.Convention);
+ var index = new Index(new List { property }, "IndexName", entityType, ConfigurationSource.Convention);
var contextServices = RelationalTestHelpers.Instance.CreateContextServices(model.FinalizeModel());
var fakeFactories = new Dictionary>