diff --git a/Directory.Build.props b/Directory.Build.props
index f9bb135989c..dd083405cee 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -16,16 +16,13 @@
Apache-2.0
-
- net5.0
-
-
MicrosoftAspNetCore
Entity Framework Core;entity-framework-core;EF;Data;O/RM;EntityFramework;EntityFrameworkCore;EFCore
Microsoft Entity Framework Core
true
- 8.0
+ nullable
+ 9.0
portable
https://docs.microsoft.com/ef/core/
diff --git a/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj b/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
index 57aeca4b90b..9d1460f2963 100644
--- a/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
+++ b/benchmark/EFCore.Benchmarks/EFCore.Benchmarks.csproj
@@ -1,34 +1,17 @@
- net461;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1
- netcoreapp3.1
+ net5.0
Microsoft.EntityFrameworkCore.Benchmarks
-
+
true
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(DefineConstants);OLD_FROM_SQL
-
-
diff --git a/benchmark/EFCore.SqlServer.Benchmarks/EFCore.SqlServer.Benchmarks.csproj b/benchmark/EFCore.SqlServer.Benchmarks/EFCore.SqlServer.Benchmarks.csproj
index bf78031a101..805190f619a 100644
--- a/benchmark/EFCore.SqlServer.Benchmarks/EFCore.SqlServer.Benchmarks.csproj
+++ b/benchmark/EFCore.SqlServer.Benchmarks/EFCore.SqlServer.Benchmarks.csproj
@@ -1,30 +1,18 @@
- net461;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1
- netcoreapp3.1
+ net5.0
Microsoft.EntityFrameworkCore.Benchmarks
Exe
-
+
true
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -34,8 +22,4 @@
-
-
-
-
diff --git a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
index 15da48e2843..d609d1abb64 100644
--- a/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
+++ b/benchmark/EFCore.Sqlite.Benchmarks/EFCore.Sqlite.Benchmarks.csproj
@@ -1,42 +1,26 @@
- net461;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1
- netcoreapp3.1
+ net5.0
Microsoft.EntityFrameworkCore.Benchmarks
Exe
-
+
true
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
Always
diff --git a/benchmark/EFCore.Sqlite.Benchmarks/Models/AdventureWorks/AdventureWorksSqliteFixture.cs b/benchmark/EFCore.Sqlite.Benchmarks/Models/AdventureWorks/AdventureWorksSqliteFixture.cs
index c40a33e1f5d..79134a4bf57 100644
--- a/benchmark/EFCore.Sqlite.Benchmarks/Models/AdventureWorks/AdventureWorksSqliteFixture.cs
+++ b/benchmark/EFCore.Sqlite.Benchmarks/Models/AdventureWorks/AdventureWorksSqliteFixture.cs
@@ -1,7 +1,6 @@
// 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;
using System.IO;
namespace Microsoft.EntityFrameworkCore.Benchmarks.Models.AdventureWorks
@@ -9,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Benchmarks.Models.AdventureWorks
public static class AdventureWorksSqliteFixture
{
private static readonly string _baseDirectory
- = Path.GetDirectoryName(new Uri(typeof(AdventureWorksSqliteFixture).Assembly.CodeBase).LocalPath);
+ = Path.GetDirectoryName(typeof(AdventureWorksSqliteFixture).Assembly.Location);
private static readonly string _connectionString
= $"Data Source={Path.Combine(_baseDirectory, "AdventureWorks2014.db")}";
diff --git a/benchmark/EFCore.Sqlite.Benchmarks/Models/Orders/OrdersSqliteFixture.cs b/benchmark/EFCore.Sqlite.Benchmarks/Models/Orders/OrdersSqliteFixture.cs
index 4526d3c6887..8e7ff4e3108 100644
--- a/benchmark/EFCore.Sqlite.Benchmarks/Models/Orders/OrdersSqliteFixture.cs
+++ b/benchmark/EFCore.Sqlite.Benchmarks/Models/Orders/OrdersSqliteFixture.cs
@@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Benchmarks.Models.Orders
public class OrdersSqliteFixture : OrdersFixtureBase
{
private static readonly string _baseDirectory
- = Path.GetDirectoryName(new Uri(typeof(OrdersSqliteFixture).Assembly.CodeBase).LocalPath);
+ = Path.GetDirectoryName(typeof(OrdersSqliteFixture).Assembly.Location);
private readonly string _connectionString;
diff --git a/src/EFCore.Abstractions/EFCore.Abstractions.csproj b/src/EFCore.Abstractions/EFCore.Abstractions.csproj
index 1826da4d11f..b38320dbb1f 100644
--- a/src/EFCore.Abstractions/EFCore.Abstractions.csproj
+++ b/src/EFCore.Abstractions/EFCore.Abstractions.csproj
@@ -2,7 +2,7 @@
Provides abstractions and attributes that are used to configure Entity Framework Core
- netstandard2.1
+ net5.0
3.6
Microsoft.EntityFrameworkCore.Abstractions
Microsoft.EntityFrameworkCore
diff --git a/src/EFCore.Cosmos/EFCore.Cosmos.csproj b/src/EFCore.Cosmos/EFCore.Cosmos.csproj
index 1f426f7b52d..7963c870192 100644
--- a/src/EFCore.Cosmos/EFCore.Cosmos.csproj
+++ b/src/EFCore.Cosmos/EFCore.Cosmos.csproj
@@ -2,7 +2,7 @@
Azure Cosmos provider for Entity Framework Core.
- netstandard2.1
+ net5.0
3.6
Microsoft.EntityFrameworkCore.Cosmos
Microsoft.EntityFrameworkCore.Cosmos
diff --git a/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs
index 9448a7e52e7..968f2dd2acf 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosQueryableExtensions.cs
@@ -1,6 +1,7 @@
// 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;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -19,9 +20,7 @@ namespace Microsoft.EntityFrameworkCore
public static class CosmosQueryableExtensions
{
internal static readonly MethodInfo WithPartitionKeyMethodInfo
- = typeof(CosmosQueryableExtensions)
- .GetTypeInfo()
- .GetDeclaredMethod(nameof(WithPartitionKey));
+ = typeof(CosmosQueryableExtensions).GetRequiredDeclaredMethod(nameof(WithPartitionKey));
///
/// Specify the partition key for partition used for the query. Required when using
@@ -33,7 +32,7 @@ internal static readonly MethodInfo WithPartitionKeyMethodInfo
/// A new query with the set partition key.
public static IQueryable WithPartitionKey(
[NotNull] this IQueryable source,
- [NotNull] [NotParameterized] string partitionKey)
+ [NotNull][NotParameterized] string partitionKey)
where TEntity : class
{
Check.NotNull(source, nameof(source));
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryMetadataExtractingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryMetadataExtractingExpressionVisitor.cs
index 95561fdaba5..7be71a4b7b9 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryMetadataExtractingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryMetadataExtractingExpressionVisitor.cs
@@ -44,8 +44,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
{
var innerQueryable = Visit(methodCallExpression.Arguments[0]);
- _cosmosQueryCompilationContext.PartitionKeyFromExtension =
- (string)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
+ _cosmosQueryCompilationContext.PartitionKeyFromExtension = methodCallExpression.Arguments[1].GetConstantValue();
return innerQueryable;
}
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs
index 9efbef8fc21..00a6900ced1 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitor.cs
@@ -30,7 +30,7 @@ protected override ProjectionExpression GetProjection(ProjectionBindingExpressio
private int GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression)
=> projectionBindingExpression.ProjectionMember != null
- ? (int)((ConstantExpression)_selectExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember)).Value
+ ? _selectExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember).GetConstantValue()
: projectionBindingExpression.Index
?? throw new InvalidOperationException(CoreStrings.QueryFailed(projectionBindingExpression.Print(), GetType().Name));
}
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs
index 63d948da8e4..f45891ee85a 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs
@@ -185,7 +185,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
var genericMethod = method.IsGenericMethod ? method.GetGenericMethodDefinition() : null;
if (genericMethod == EntityFrameworkCore.Infrastructure.ExpressionExtensions.ValueBufferTryReadValueMethod)
{
- var property = (IProperty)((ConstantExpression)methodCallExpression.Arguments[2]).Value;
+ var property = methodCallExpression.Arguments[2].GetConstantValue();
Expression innerExpression;
if (methodCallExpression.Arguments[0] is ProjectionBindingExpression projectionBindingExpression)
{
diff --git a/src/EFCore.Cosmos/Query/Internal/SqlConstantExpression.cs b/src/EFCore.Cosmos/Query/Internal/SqlConstantExpression.cs
index 9ae14e80e65..a7447b13ff5 100644
--- a/src/EFCore.Cosmos/Query/Internal/SqlConstantExpression.cs
+++ b/src/EFCore.Cosmos/Query/Internal/SqlConstantExpression.cs
@@ -44,7 +44,7 @@ public SqlConstantExpression([NotNull] ConstantExpression constantExpression, [C
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public virtual object Value
+ public virtual object? Value
=> _constantExpression.Value;
///
@@ -83,7 +83,7 @@ protected override void Print(ExpressionPrinter expressionPrinter)
}
private void Print(
- object value,
+ object? value,
ExpressionPrinter expressionPrinter)
{
if (value is IEnumerable enumerable
@@ -110,7 +110,7 @@ private void Print(
}
}
- private JToken? GenerateJToken(object value, CoreTypeMapping? typeMapping)
+ private JToken? GenerateJToken(object? value, CoreTypeMapping? typeMapping)
{
var mappingClrType = typeMapping?.ClrType.UnwrapNullableType() ?? Type;
if (value?.GetType().IsInteger() == true
diff --git a/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs b/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs
index c19d9758832..3a1f03cf511 100644
--- a/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs
+++ b/src/EFCore.Cosmos/Query/Internal/SqlParameterExpression.cs
@@ -21,6 +21,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
public sealed class SqlParameterExpression : SqlExpression
{
private readonly ParameterExpression _parameterExpression;
+ private readonly string _name;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -31,7 +32,10 @@ public sealed class SqlParameterExpression : SqlExpression
public SqlParameterExpression([NotNull] ParameterExpression parameterExpression, [CanBeNull] CoreTypeMapping? typeMapping)
: base(parameterExpression.Type, typeMapping)
{
+ Check.DebugAssert(parameterExpression.Name != null, "Parameter must have name.");
+
_parameterExpression = parameterExpression;
+ _name = parameterExpression.Name;
}
///
@@ -41,7 +45,7 @@ public SqlParameterExpression([NotNull] ParameterExpression parameterExpression,
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public string Name
- => _parameterExpression.Name;
+ => _name;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore.Cosmos/Query/Internal/StringMethodTranslator.cs b/src/EFCore.Cosmos/Query/Internal/StringMethodTranslator.cs
index dcc3e6e686c..82adc07ab49 100644
--- a/src/EFCore.Cosmos/Query/Internal/StringMethodTranslator.cs
+++ b/src/EFCore.Cosmos/Query/Internal/StringMethodTranslator.cs
@@ -22,13 +22,13 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
public class StringMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _containsMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Contains), new[] { typeof(string) });
private static readonly MethodInfo _startsWithMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
private static readonly MethodInfo _endsWithMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
private static readonly MethodInfo _firstOrDefaultMethodInfoWithoutArgs
= typeof(Enumerable).GetRuntimeMethods().Single(
diff --git a/src/EFCore.Design/EFCore.Design.csproj b/src/EFCore.Design/EFCore.Design.csproj
index 5ba1cc823c6..ea9b3b0e3a1 100644
--- a/src/EFCore.Design/EFCore.Design.csproj
+++ b/src/EFCore.Design/EFCore.Design.csproj
@@ -2,7 +2,7 @@
Shared design-time components for Entity Framework Core tools.
- netstandard2.1
+ net5.0
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore
true
@@ -31,7 +31,6 @@
-
diff --git a/src/EFCore.Design/build/netcoreapp3.0/Microsoft.EntityFrameworkCore.Design.props b/src/EFCore.Design/build/net5.0/Microsoft.EntityFrameworkCore.Design.props
similarity index 100%
rename from src/EFCore.Design/build/netcoreapp3.0/Microsoft.EntityFrameworkCore.Design.props
rename to src/EFCore.Design/build/net5.0/Microsoft.EntityFrameworkCore.Design.props
diff --git a/src/EFCore.InMemory/EFCore.InMemory.csproj b/src/EFCore.InMemory/EFCore.InMemory.csproj
index 4ce6274ada6..b400607e4a9 100644
--- a/src/EFCore.InMemory/EFCore.InMemory.csproj
+++ b/src/EFCore.InMemory/EFCore.InMemory.csproj
@@ -2,7 +2,7 @@
In-memory database provider for Entity Framework Core (to be used for testing purposes).
- netstandard2.1
+ net5.0
3.6
Microsoft.EntityFrameworkCore.InMemory
Microsoft.EntityFrameworkCore.InMemory
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs
index 77e11725141..97274768353 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs
@@ -37,22 +37,22 @@ public class InMemoryExpressionTranslatingExpressionVisitor : ExpressionVisitor
private static readonly MemberInfo _valueBufferIsEmpty = typeof(ValueBuffer).GetMember(nameof(ValueBuffer.IsEmpty))[0];
private static readonly MethodInfo _parameterValueExtractor =
- typeof(InMemoryExpressionTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(ParameterValueExtractor));
+ typeof(InMemoryExpressionTranslatingExpressionVisitor).GetRequiredDeclaredMethod(nameof(ParameterValueExtractor));
private static readonly MethodInfo _parameterListValueExtractor =
- typeof(InMemoryExpressionTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(ParameterListValueExtractor));
+ typeof(InMemoryExpressionTranslatingExpressionVisitor).GetRequiredDeclaredMethod(nameof(ParameterListValueExtractor));
private static readonly MethodInfo _getParameterValueMethodInfo =
- typeof(InMemoryExpressionTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(GetParameterValue));
+ typeof(InMemoryExpressionTranslatingExpressionVisitor).GetRequiredDeclaredMethod(nameof(GetParameterValue));
- private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions).GetRuntimeMethod(
+ private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions).GetRequiredRuntimeMethod(
nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string) });
- private static readonly MethodInfo _likeMethodInfoWithEscape = typeof(DbFunctionsExtensions).GetRuntimeMethod(
+ private static readonly MethodInfo _likeMethodInfoWithEscape = typeof(DbFunctionsExtensions).GetRequiredRuntimeMethod(
nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) });
private static readonly MethodInfo _inMemoryLikeMethodInfo =
- typeof(InMemoryExpressionTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(InMemoryLike));
+ typeof(InMemoryExpressionTranslatingExpressionVisitor).GetRequiredDeclaredMethod(nameof(InMemoryLike));
// Regex special chars defined here:
// https://msdn.microsoft.com/en-us/library/4edbef7e(v=vs.110).aspx
@@ -134,7 +134,8 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
{
var result = Visit(expression);
- return _entityReferenceFindingExpressionVisitor.Find(result)
+ return result == QueryCompilationContext.NotTranslatedExpression
+ || _entityReferenceFindingExpressionVisitor.Find(result)
? null
: result;
}
@@ -145,7 +146,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitBinary(BinaryExpression binaryExpression)
+ protected override Expression VisitBinary(BinaryExpression binaryExpression)
{
Check.NotNull(binaryExpression, nameof(binaryExpression));
@@ -159,10 +160,10 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
var newLeft = Visit(binaryExpression.Left);
var newRight = Visit(binaryExpression.Right);
- if (newLeft == null
- || newRight == null)
+ if (newLeft == QueryCompilationContext.NotTranslatedExpression
+ || newRight == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if ((binaryExpression.NodeType == ExpressionType.Equal
@@ -225,7 +226,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitConditional(ConditionalExpression conditionalExpression)
+ protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
{
Check.NotNull(conditionalExpression, nameof(conditionalExpression));
@@ -233,11 +234,11 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
var ifTrue = Visit(conditionalExpression.IfTrue);
var ifFalse = Visit(conditionalExpression.IfFalse);
- if (test == null
- || ifTrue == null
- || ifFalse == null)
+ if (test == QueryCompilationContext.NotTranslatedExpression
+ || ifTrue == QueryCompilationContext.NotTranslatedExpression
+ || ifFalse == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (test.Type == typeof(bool?))
@@ -261,7 +262,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitExtension(Expression extensionExpression)
+ protected override Expression VisitExtension(Expression extensionExpression)
{
Check.NotNull(extensionExpression, nameof(extensionExpression));
@@ -278,7 +279,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
return projectionBindingExpression.ProjectionMember != null
? ((InMemoryQueryExpression)projectionBindingExpression.QueryExpression)
.GetMappedProjection(projectionBindingExpression.ProjectionMember)
- : null;
+ : QueryCompilationContext.NotTranslatedExpression;
case InMemoryGroupByShaperExpression inMemoryGroupByShaperExpression:
return new GroupingElementExpression(
@@ -287,7 +288,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
inMemoryGroupByShaperExpression.ValueBufferParameter);
default:
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
}
@@ -297,8 +298,8 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitInvocation(InvocationExpression invocationExpression)
- => null;
+ protected override Expression VisitInvocation(InvocationExpression invocationExpression)
+ => QueryCompilationContext.NotTranslatedExpression;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -306,8 +307,8 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitLambda(Expression lambdaExpression)
- => null;
+ protected override Expression VisitLambda(Expression lambdaExpression)
+ => QueryCompilationContext.NotTranslatedExpression;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -315,8 +316,8 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitListInit(ListInitExpression listInitExpression)
- => null;
+ protected override Expression VisitListInit(ListInitExpression listInitExpression)
+ => QueryCompilationContext.NotTranslatedExpression;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -324,15 +325,15 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitMember(MemberExpression memberExpression)
+ protected override Expression VisitMember(MemberExpression memberExpression)
{
Check.NotNull(memberExpression, nameof(memberExpression));
var innerExpression = Visit(memberExpression.Expression);
if (memberExpression.Expression != null
- && innerExpression == null)
+ && innerExpression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (TryBindMember(innerExpression, MemberIdentity.Create(memberExpression.Member), memberExpression.Type) is Expression result)
@@ -367,12 +368,12 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override MemberAssignment? VisitMemberAssignment(MemberAssignment memberAssignment)
+ protected override MemberAssignment VisitMemberAssignment(MemberAssignment memberAssignment)
{
var expression = Visit(memberAssignment.Expression);
- if (expression == null)
+ if (expression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return memberAssignment.Update(Expression.Convert(expression, memberAssignment.Expression.Type));
}
if (IsConvertedToNullable(expression, memberAssignment.Expression))
@@ -389,7 +390,43 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitMethodCall(MethodCallExpression methodCallExpression)
+ protected override Expression VisitMemberInit(MemberInitExpression memberInitExpression)
+ {
+ Check.NotNull(memberInitExpression, nameof(memberInitExpression));
+
+ var newExpression = Visit(memberInitExpression.NewExpression);
+ if (newExpression == QueryCompilationContext.NotTranslatedExpression)
+ {
+ return QueryCompilationContext.NotTranslatedExpression;
+ }
+
+ var newBindings = new MemberBinding[memberInitExpression.Bindings.Count];
+ for (var i = 0; i < newBindings.Length; i++)
+ {
+ if (memberInitExpression.Bindings[i].BindingType != MemberBindingType.Assignment)
+ {
+ return QueryCompilationContext.NotTranslatedExpression;
+ }
+
+ newBindings[i] = VisitMemberBinding(memberInitExpression.Bindings[i]);
+ if (((MemberAssignment)newBindings[i]).Expression is UnaryExpression unaryExpression
+ && unaryExpression.NodeType == ExpressionType.Convert
+ && unaryExpression.Operand == QueryCompilationContext.NotTranslatedExpression)
+ {
+ return QueryCompilationContext.NotTranslatedExpression;
+ }
+ }
+
+ return memberInitExpression.Update((NewExpression)newExpression, newBindings);
+ }
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
Check.NotNull(methodCallExpression, nameof(methodCallExpression));
@@ -409,7 +446,8 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
// EF Indexer property
if (methodCallExpression.TryGetIndexerArguments(_model, out source, out propertyName))
{
- return TryBindMember(Visit(source), MemberIdentity.Create(propertyName), methodCallExpression.Type);
+ return TryBindMember(Visit(source), MemberIdentity.Create(propertyName), methodCallExpression.Type)
+ ?? QueryCompilationContext.NotTranslatedExpression;
}
// GroupBy Aggregate case
@@ -436,7 +474,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
result = expression == null
? null
: Expression.Call(
- EnumerableMethods.GetAverageWithoutSelector(expression.Type.TryGetSequenceType()!), expression);
+ EnumerableMethods.GetAverageWithoutSelector(expression.Type.GetSequenceType()), expression);
break;
}
@@ -461,7 +499,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
result = expression == null
? null
: Expression.Call(
- EnumerableMethods.CountWithoutPredicate.MakeGenericMethod(expression.Type.TryGetSequenceType()),
+ EnumerableMethods.CountWithoutPredicate.MakeGenericMethod(expression.Type.GetSequenceType()),
expression);
break;
}
@@ -495,7 +533,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
result = expression == null
? null
: Expression.Call(
- EnumerableMethods.LongCountWithoutPredicate.MakeGenericMethod(expression.Type.TryGetSequenceType()),
+ EnumerableMethods.LongCountWithoutPredicate.MakeGenericMethod(expression.Type.GetSequenceType()),
expression);
break;
}
@@ -516,7 +554,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
}
else
{
- var type = expression.Type.TryGetSequenceType()!;
+ var type = expression.Type.GetSequenceType();
var aggregateMethod = EnumerableMethods.GetMaxWithoutSelector(type);
if (aggregateMethod.IsGenericMethod)
{
@@ -545,7 +583,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
}
else
{
- var type = expression.Type.TryGetSequenceType()!;
+ var type = expression.Type.GetSequenceType();
var aggregateMethod = EnumerableMethods.GetMinWithoutSelector(type);
if (aggregateMethod.IsGenericMethod)
{
@@ -575,7 +613,7 @@ static bool ShouldApplyNullProtectionForMemberAccess(Type callerType, string mem
result = expression == null
? null
: Expression.Call(
- EnumerableMethods.GetSumWithoutSelector(expression.Type.TryGetSequenceType()!), expression);
+ EnumerableMethods.GetSumWithoutSelector(expression.Type.GetSequenceType()), expression);
break;
}
@@ -651,7 +689,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
var subquery = (InMemoryQueryExpression)subqueryTranslation.QueryExpression;
if (subqueryTranslation.ResultCardinality == ResultCardinality.Enumerable)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
var shaperExpression = subqueryTranslation.ShaperExpression;
@@ -675,13 +713,13 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
&& (convertedType == null
|| convertedType.MakeNullable() == innerExpression.Type)))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (projectionBindingExpression.ProjectionMember == null)
{
// We don't lift scalar subquery with client eval
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
return ProcessSingleResultScalar(
@@ -703,7 +741,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
var argument = Visit(methodCallExpression.Arguments[i]);
if (TranslationFailed(methodCallExpression.Arguments[i], argument))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
visitedArguments[i - 1] = argument;
@@ -721,22 +759,22 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
&& methodCallExpression.Arguments.Count == 1)
{
var left = Visit(methodCallExpression.Object);
- var right = Visit(methodCallExpression.Arguments[0]);
+ var right = Visit(methodCallExpression.Arguments[0])!;
if (TryRewriteEntityEquality(
ExpressionType.Equal,
- left ?? methodCallExpression.Object,
- right ?? methodCallExpression.Arguments[0],
+ left == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Object : left,
+ right == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Arguments[0] : right,
equalsMethod: true,
out var result))
{
return result;
}
- if (TranslationFailed(left)
- || TranslationFailed(right))
+ if (TranslationFailed(methodCallExpression.Object, left)
+ || TranslationFailed(methodCallExpression.Arguments[0], right))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
@object = left;
@@ -754,23 +792,23 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
methodCallExpression.Arguments[0], methodCallExpression.Arguments[1]));
}
- var left = Visit(methodCallExpression.Arguments[0]);
- var right = Visit(methodCallExpression.Arguments[1]);
+ var left = Visit(methodCallExpression.Arguments[0])!;
+ var right = Visit(methodCallExpression.Arguments[1])!;
if (TryRewriteEntityEquality(
ExpressionType.Equal,
- left ?? methodCallExpression.Arguments[0],
- right ?? methodCallExpression.Arguments[1],
+ left == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Arguments[0] : left,
+ right == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Arguments[1] : right,
equalsMethod: true,
out var result))
{
return result;
}
- if (TranslationFailed(left)
- || TranslationFailed(right))
+ if (TranslationFailed(methodCallExpression.Arguments[0], left)
+ || TranslationFailed(methodCallExpression.Arguments[1], right))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
arguments = new Expression[2] { left, right };
@@ -778,18 +816,20 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
else if (method.IsGenericMethod
&& method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains))
{
- var enumerable = Visit(methodCallExpression.Arguments[0]);
- var item = Visit(methodCallExpression.Arguments[1]);
+ var enumerable = Visit(methodCallExpression.Arguments[0])!;
+ var item = Visit(methodCallExpression.Arguments[1])!;
- if (TryRewriteContainsEntity(enumerable, item ?? methodCallExpression.Arguments[1], out var result))
+ if (TryRewriteContainsEntity(enumerable,
+ item == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Arguments[1] : item,
+ out var result))
{
return result;
}
- if (TranslationFailed(enumerable)
- || TranslationFailed(item))
+ if (TranslationFailed(methodCallExpression.Arguments[0], enumerable)
+ || TranslationFailed(methodCallExpression.Arguments[1], item))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
arguments = new Expression[2] { enumerable, item };
@@ -798,17 +838,19 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
&& method.IsContainsMethod())
{
var enumerable = Visit(methodCallExpression.Object);
- var item = Visit(methodCallExpression.Arguments[0]);
+ var item = Visit(methodCallExpression.Arguments[0])!;
- if (TryRewriteContainsEntity(enumerable, item ?? methodCallExpression.Arguments[0], out var result))
+ if (TryRewriteContainsEntity(enumerable,
+ item == QueryCompilationContext.NotTranslatedExpression ? methodCallExpression.Arguments[0] : item,
+ out var result))
{
return result;
}
- if (TranslationFailed(enumerable)
- || TranslationFailed(item))
+ if (TranslationFailed(methodCallExpression.Object, enumerable)
+ || TranslationFailed(methodCallExpression.Arguments[0], item))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
@object = enumerable;
@@ -819,7 +861,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
@object = Visit(methodCallExpression.Object);
if (TranslationFailed(methodCallExpression.Object, @object))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
arguments = new Expression[methodCallExpression.Arguments.Count];
@@ -828,7 +870,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
var argument = Visit(methodCallExpression.Arguments[i]);
if (TranslationFailed(methodCallExpression.Arguments[i], argument))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
arguments[i] = argument;
@@ -869,7 +911,8 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
return result;
}
- return methodCallExpression.Update(@object, arguments);
+ // TODO-Nullable bug
+ return methodCallExpression.Update(@object!, arguments);
}
///
@@ -878,7 +921,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitNew(NewExpression newExpression)
+ protected override Expression VisitNew(NewExpression newExpression)
{
Check.NotNull(newExpression, nameof(newExpression));
@@ -886,9 +929,9 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
foreach (var argument in newExpression.Arguments)
{
var newArgument = Visit(argument);
- if (newArgument == null)
+ if (newArgument == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (IsConvertedToNullable(newArgument, argument))
@@ -908,7 +951,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitNewArray(NewArrayExpression newArrayExpression)
+ protected override Expression VisitNewArray(NewArrayExpression newArrayExpression)
{
Check.NotNull(newArrayExpression, nameof(newArrayExpression));
@@ -916,9 +959,9 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
foreach (var expression in newArrayExpression.Expressions)
{
var newExpression = Visit(expression);
- if (newExpression == null)
+ if (newExpression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (IsConvertedToNullable(newExpression, expression))
@@ -938,7 +981,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitParameter(ParameterExpression parameterExpression)
+ protected override Expression VisitParameter(ParameterExpression parameterExpression)
{
Check.NotNull(parameterExpression, nameof(parameterExpression));
@@ -959,7 +1002,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitTypeBinary(TypeBinaryExpression typeBinaryExpression)
+ protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExpression)
{
Check.NotNull(typeBinaryExpression, nameof(typeBinaryExpression));
@@ -999,7 +1042,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
}
}
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
///
@@ -1008,14 +1051,14 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitUnary(UnaryExpression unaryExpression)
+ protected override Expression VisitUnary(UnaryExpression unaryExpression)
{
Check.NotNull(unaryExpression, nameof(unaryExpression));
var newOperand = Visit(unaryExpression.Operand);
- if (newOperand == null)
+ if (newOperand == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (newOperand is EntityReferenceExpression entityReferenceExpression
@@ -1063,7 +1106,7 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
return result;
}
- private Expression? TryBindMember(Expression source, MemberIdentity member, Type type)
+ private Expression? TryBindMember(Expression? source, MemberIdentity member, Type type)
{
if (!(source is EntityReferenceExpression entityReferenceExpression))
{
@@ -1093,8 +1136,13 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
{
if (entityReferenceExpression.ParameterEntity != null)
{
- var result = ((EntityProjectionExpression)Visit(entityReferenceExpression.ParameterEntity.ValueBufferExpression))
- .BindProperty(property);
+ var valueBufferExpression = Visit(entityReferenceExpression.ParameterEntity.ValueBufferExpression);
+ if (valueBufferExpression == QueryCompilationContext.NotTranslatedExpression)
+ {
+ return null;
+ }
+
+ var result = ((EntityProjectionExpression)valueBufferExpression).BindProperty(property);
// if the result type change was just nullability change e.g from int to int?
// we want to preserve the new type for null propagation
@@ -1174,7 +1222,7 @@ private static Expression ProcessSingleResultScalar(
[UsedImplicitly]
private static T GetParameterValue(QueryContext queryContext, string parameterName)
- => (T)queryContext.ParameterValues[parameterName];
+ => (T)queryContext.ParameterValues[parameterName]!;
private static bool IsConvertedToNullable(Expression result, Expression original)
=> result.Type.IsNullableType()
@@ -1205,13 +1253,13 @@ private static Expression ConvertToNonNullable(Expression expression)
&& readValueMethodCall.Method.IsGenericMethod
&& readValueMethodCall.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod)
{
- return (IProperty)((ConstantExpression)readValueMethodCall.Arguments[2]).Value;
+ return readValueMethodCall.Arguments[2].GetConstantValue();
}
return null;
}
- private bool TryRewriteContainsEntity(Expression source, Expression item, [CA.NotNullWhen(true)] out Expression? result)
+ private bool TryRewriteContainsEntity(Expression? source, Expression item, [CA.NotNullWhen(true)] out Expression? result)
{
result = null;
@@ -1239,9 +1287,9 @@ private bool TryRewriteContainsEntity(Expression source, Expression item, [CA.No
switch (source)
{
case ConstantExpression constantExpression:
- var values = (IEnumerable)constantExpression.Value;
+ var values = constantExpression.GetConstantValue();
var propertyValueList =
- (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(property.ClrType.MakeNullable()));
+ (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(property.ClrType.MakeNullable()))!;
var propertyGetter = property.GetGetter();
foreach (var value in values)
{
@@ -1254,10 +1302,10 @@ private bool TryRewriteContainsEntity(Expression source, Expression item, [CA.No
case MethodCallExpression methodCallExpression
when methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == _getParameterValueMethodInfo:
- var parameterName = (string)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
+ var parameterName = methodCallExpression.Arguments[1].GetConstantValue();
var lambda = Expression.Lambda(
Expression.Call(
- _parameterListValueExtractor.MakeGenericMethod(entityType.ClrType, property.ClrType.MakeNullable()),
+ _parameterListValueExtractor.MakeGenericMethod(entityType.ClrType!, property.ClrType.MakeNullable()),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(parameterName, typeof(string)),
Expression.Constant(property, typeof(IProperty))),
@@ -1381,7 +1429,7 @@ private Expression CreatePropertyAccessExpression(Expression target, IProperty p
case MethodCallExpression methodCallExpression
when methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == _getParameterValueMethodInfo:
- var parameterName = (string)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
+ var parameterName = methodCallExpression.Arguments[1].GetConstantValue();
var lambda = Expression.Lambda(
Expression.Call(
_parameterValueExtractor.MakeGenericMethod(property.ClrType.MakeNullable()),
@@ -1504,10 +1552,8 @@ private static bool IsNullConstantExpression(Expression expression)
[DebuggerStepThrough]
private static bool TranslationFailed(Expression? original, Expression? translation)
- => original != null && TranslationFailed(translation);
-
- private static bool TranslationFailed([CA.NotNullWhen(false)] Expression? translation)
- => translation == null || translation is EntityReferenceExpression;
+ => original != null
+ && (translation == QueryCompilationContext.NotTranslatedExpression || translation is EntityReferenceExpression);
private static bool InMemoryLike(string matchExpression, string pattern, string escapeCharacter)
{
@@ -1603,7 +1649,8 @@ public bool Find(Expression expression)
return _found;
}
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (_found)
{
@@ -1652,7 +1699,7 @@ public override Type Type
public override ExpressionType NodeType
=> ExpressionType.Extension;
- public Expression? Convert(Type type)
+ public Expression Convert(Type type)
{
if (type == typeof(object) // Ignore object conversion
|| type.IsAssignableFrom(Type)) // Ignore casting to base type/interface
@@ -1662,7 +1709,9 @@ public override ExpressionType NodeType
var derivedEntityType = EntityType.GetDerivedTypes().FirstOrDefault(et => et.ClrType == type);
- return derivedEntityType == null ? null : new EntityReferenceExpression(this, derivedEntityType);
+ return derivedEntityType == null
+ ? QueryCompilationContext.NotTranslatedExpression
+ : new EntityReferenceExpression(this, derivedEntityType);
}
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
index 01ba22955e7..52e47c5051c 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryProjectionBindingExpressionVisitor.cs
@@ -12,6 +12,7 @@
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -67,7 +68,7 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
var expandedExpression = _queryableMethodTranslatingExpressionVisitor.ExpandWeakEntities(_queryExpression, expression);
var result = Visit(expandedExpression);
- if (result == null)
+ if (result == QueryCompilationContext.NotTranslatedExpression)
{
_clientEval = true;
@@ -93,6 +94,7 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
/// 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.NotNullIfNotNull("expression")]
public override Expression? Visit(Expression? expression)
{
if (expression == null)
@@ -125,7 +127,7 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
_queryableMethodTranslatingExpressionVisitor.TranslateSubquery(
materializeCollectionNavigationExpression.Subquery)!,
materializeCollectionNavigationExpression.Navigation,
- materializeCollectionNavigationExpression.Navigation.ClrType.TryGetSequenceType()!);
+ materializeCollectionNavigationExpression.Navigation.ClrType.GetSequenceType());
case MethodCallExpression methodCallExpression:
{
@@ -179,7 +181,7 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
var translation = _expressionTranslatingExpressionVisitor.Translate(expression);
if (translation == null)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
_projectionMapping[_projectionMembers.Peek()] = translation;
@@ -199,8 +201,8 @@ public virtual Expression Translate([NotNull] InMemoryQueryExpression queryExpre
///
protected override Expression VisitBinary(BinaryExpression binaryExpression)
{
- var left = MatchTypes(Visit(binaryExpression.Left)!, binaryExpression.Left.Type);
- var right = MatchTypes(Visit(binaryExpression.Right)!, binaryExpression.Right.Type);
+ var left = MatchTypes(Visit(binaryExpression.Left), binaryExpression.Left.Type);
+ var right = MatchTypes(Visit(binaryExpression.Right), binaryExpression.Right.Type);
return binaryExpression.Update(left, VisitAndConvert(binaryExpression.Conversion, "VisitBinary"), right);
}
@@ -213,9 +215,9 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
///
protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
{
- var test = Visit(conditionalExpression.Test)!;
- var ifTrue = Visit(conditionalExpression.IfTrue)!;
- var ifFalse = Visit(conditionalExpression.IfFalse)!;
+ var test = Visit(conditionalExpression.Test);
+ var ifTrue = Visit(conditionalExpression.IfTrue);
+ var ifFalse = Visit(conditionalExpression.IfFalse);
if (test.Type == typeof(bool?))
{
@@ -231,7 +233,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitExtension(Expression extensionExpression)
+ protected override Expression VisitExtension(Expression extensionExpression)
{
Check.NotNull(extensionExpression, nameof(extensionExpression));
@@ -243,7 +245,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
if (projectionBindingExpression.ProjectionMember == null)
{
// We don't process binding with client projection
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
entityProjectionExpression = (EntityProjectionExpression)((InMemoryQueryExpression)projectionBindingExpression.QueryExpression)
@@ -270,7 +272,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
{
return _clientEval
? base.VisitExtension(includeExpression)
- : null;
+ : QueryCompilationContext.NotTranslatedExpression;
}
throw new InvalidOperationException(CoreStrings.QueryFailed(extensionExpression.Print(), GetType().Name));
@@ -283,7 +285,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
protected override ElementInit VisitElementInit(ElementInit elementInit)
- => elementInit.Update(elementInit.Arguments.Select(e => MatchTypes(Visit(e)!, e.Type)));
+ => elementInit.Update(elementInit.Arguments.Select(e => MatchTypes(Visit(e), e.Type)));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -295,7 +297,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
{
var expression = Visit(memberExpression.Expression);
Expression updatedMemberExpression = memberExpression.Update(
- expression != null ? MatchTypes(expression, memberExpression.Expression.Type) : expression);
+ expression != null ? MatchTypes(expression, memberExpression.Expression!.Type) : expression);
if (expression?.Type.IsNullableValueType() == true)
{
@@ -320,7 +322,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override MemberAssignment? VisitMemberAssignment(MemberAssignment memberAssignment)
+ protected override MemberAssignment VisitMemberAssignment(MemberAssignment memberAssignment)
{
var expression = memberAssignment.Expression;
Expression? visitedExpression;
@@ -334,15 +336,15 @@ protected override Expression VisitMember(MemberExpression memberExpression)
_projectionMembers.Push(projectionMember);
visitedExpression = Visit(memberAssignment.Expression);
- if (visitedExpression == null)
+ if (visitedExpression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return memberAssignment.Update(Expression.Convert(visitedExpression, memberAssignment.Expression.Type));
}
_projectionMembers.Pop();
}
- visitedExpression = MatchTypes(visitedExpression!, expression.Type);
+ visitedExpression = MatchTypes(visitedExpression, expression.Type);
return memberAssignment.Update(visitedExpression);
}
@@ -353,14 +355,14 @@ protected override Expression VisitMember(MemberExpression memberExpression)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitMemberInit(MemberInitExpression memberInitExpression)
+ protected override Expression VisitMemberInit(MemberInitExpression memberInitExpression)
{
Check.NotNull(memberInitExpression, nameof(memberInitExpression));
var newExpression = Visit(memberInitExpression.NewExpression);
- if (newExpression == null)
+ if (newExpression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
var newBindings = new MemberBinding[memberInitExpression.Bindings.Count];
@@ -368,13 +370,15 @@ protected override Expression VisitMember(MemberExpression memberExpression)
{
if (memberInitExpression.Bindings[i].BindingType != MemberBindingType.Assignment)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
newBindings[i] = VisitMemberBinding(memberInitExpression.Bindings[i]);
- if (newBindings[i] == null)
+ if (((MemberAssignment)newBindings[i]).Expression is UnaryExpression unaryExpression
+ && unaryExpression.NodeType == ExpressionType.Convert
+ && unaryExpression.Operand == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
}
@@ -394,15 +398,15 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
for (var i = 0; i < methodCallExpression.Arguments.Count; i++)
{
var argument = methodCallExpression.Arguments[i];
- arguments[i] = MatchTypes(Visit(argument)!, argument.Type);
+ arguments[i] = MatchTypes(Visit(argument), argument.Type);
}
Expression updatedMethodCallExpression = methodCallExpression.Update(
- @object != null ? MatchTypes(@object, methodCallExpression.Object.Type) : @object,
+ @object != null ? MatchTypes(@object, methodCallExpression.Object!.Type) : @object!,
arguments);
if (@object?.Type.IsNullableType() == true
- && !methodCallExpression.Object.Type.IsNullableType())
+ && !methodCallExpression.Object!.Type.IsNullableType())
{
var nullableReturnType = methodCallExpression.Type.MakeNullable();
if (!methodCallExpression.Type.IsNullableType())
@@ -425,7 +429,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitNew(NewExpression newExpression)
+ protected override Expression VisitNew(NewExpression newExpression)
{
Check.NotNull(newExpression, nameof(newExpression));
@@ -437,7 +441,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
if (!_clientEval
&& newExpression.Members == null)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
var newArguments = new Expression[newExpression.Arguments.Count];
@@ -451,18 +455,18 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
}
else
{
- var projectionMember = _projectionMembers.Peek().Append(newExpression.Members[i]);
+ var projectionMember = _projectionMembers.Peek().Append(newExpression.Members![i]);
_projectionMembers.Push(projectionMember);
visitedArgument = Visit(argument);
- if (visitedArgument == null)
+ if (visitedArgument == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
_projectionMembers.Pop();
}
- newArguments[i] = MatchTypes(visitedArgument!, argument.Type);
+ newArguments[i] = MatchTypes(visitedArgument, argument.Type);
}
return newExpression.Update(newArguments);
@@ -475,7 +479,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
protected override Expression VisitNewArray(NewArrayExpression newArrayExpression)
- => newArrayExpression.Update(newArrayExpression.Expressions.Select(e => MatchTypes(Visit(e)!, e.Type)));
+ => newArrayExpression.Update(newArrayExpression.Expressions.Select(e => MatchTypes(Visit(e), e.Type)));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -485,7 +489,7 @@ protected override Expression VisitNewArray(NewArrayExpression newArrayExpressio
///
protected override Expression VisitUnary(UnaryExpression unaryExpression)
{
- var operand = Visit(unaryExpression.Operand)!;
+ var operand = Visit(unaryExpression.Operand);
return (unaryExpression.NodeType == ExpressionType.Convert
|| unaryExpression.NodeType == ExpressionType.ConvertChecked)
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
index b0656bb5bd3..6d968e8ca77 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
@@ -14,6 +14,7 @@
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
using ExpressionExtensions = Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions;
#nullable enable
@@ -32,7 +33,7 @@ private static readonly ConstructorInfo _valueBufferConstructor
= typeof(ValueBuffer).GetConstructors().Single(ci => ci.GetParameters().Length == 1);
private static readonly PropertyInfo _valueBufferCountMemberInfo
- = typeof(ValueBuffer).GetProperty(nameof(ValueBuffer.Count));
+ = typeof(ValueBuffer).GetRequiredProperty(nameof(ValueBuffer.Count));
private readonly List _valueBufferSlots = new List();
@@ -248,8 +249,8 @@ public virtual int AddSubqueryProjection(
var terminatingMethodCall =
(MethodCallExpression)((LambdaExpression)((NewExpression)selectMethodCall.Arguments[0]).Arguments[0]).Body;
selectMethodCall = selectMethodCall.Update(
- null, new[] { terminatingMethodCall.Arguments[0], selectMethodCall.Arguments[1] });
- serverQueryExpression = terminatingMethodCall.Update(null, new[] { selectMethodCall });
+ null!, new[] { terminatingMethodCall.Arguments[0], selectMethodCall.Arguments[1] });
+ serverQueryExpression = terminatingMethodCall.Update(null!, new[] { selectMethodCall });
}
innerShaper = new ShaperRemappingExpressionVisitor(subquery._projectionMapping)
@@ -269,7 +270,8 @@ public ShaperRemappingExpressionVisitor(IDictionary expression is MethodCallExpression methodCallExpression
&& methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod
- ? (IPropertyBase)((ConstantExpression)methodCallExpression.Arguments[2]).Value
+ ? methodCallExpression.Arguments[2].GetConstantValue()
: null;
///
@@ -603,7 +605,7 @@ public virtual void AddInnerJoin(
new Expression[] { outerParameter, innerParameter });
var index = 0;
- var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
+ var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
foreach (var projection in _projectionMapping)
{
if (projection.Value is EntityProjectionExpression entityProjection)
@@ -627,7 +629,7 @@ public virtual void AddInnerJoin(
}
}
- var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
foreach (var projection in innerQueryExpression._projectionMapping)
{
if (projection.Value is EntityProjectionExpression entityProjection)
@@ -691,8 +693,8 @@ public virtual void AddLeftJoin(
typeof(ValueBuffer), typeof(IEnumerable));
var outerParameter = Parameter(typeof(ValueBuffer), "outer");
var innerParameter = Parameter(typeof(IEnumerable), "inner");
- var outerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var innerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var outerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var innerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var resultSelector = Lambda(
New(
groupTransparentIdentifierType.GetTypeInfo().DeclaredConstructors.Single(),
@@ -722,7 +724,7 @@ public virtual void AddLeftJoin(
new Expression[] { MakeMemberAccess(outerParameter, outerMemberInfo), innerParameter });
var index = 0;
- outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
+ outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
foreach (var projection in _projectionMapping)
{
if (projection.Value is EntityProjectionExpression entityProjection)
@@ -748,7 +750,7 @@ public virtual void AddLeftJoin(
}
var outerIndex = index;
- innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var nullableReadValueExpressionVisitor = new NullableReadValueExpressionVisitor();
foreach (var projection in innerQueryExpression._projectionMapping)
{
@@ -828,7 +830,7 @@ public virtual void AddSelectMany(
new Expression[] { outerParameter, innerParameter });
var index = 0;
- var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
+ var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
foreach (var projection in _projectionMapping)
{
if (projection.Value is EntityProjectionExpression entityProjection)
@@ -852,7 +854,7 @@ public virtual void AddSelectMany(
}
}
- var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var nullableReadValueExpressionVisitor = new NullableReadValueExpressionVisitor();
foreach (var projection in innerQueryExpression._projectionMapping)
{
@@ -927,8 +929,8 @@ public virtual EntityShaperExpression AddNavigationToWeakEntityType(
typeof(ValueBuffer), typeof(IEnumerable));
var outerParameter = Parameter(typeof(ValueBuffer), "outer");
var innerParameter = Parameter(typeof(IEnumerable), "inner");
- var outerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var innerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var outerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var innerMemberInfo = groupTransparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var resultSelector = Lambda(
New(
groupTransparentIdentifierType.GetTypeInfo().DeclaredConstructors.Single(),
@@ -1066,7 +1068,7 @@ EntityProjectionExpression CopyEntityProjectionToOuter(EntityProjectionExpressio
static int GetValueBufferIndex(Expression expression)
=> expression is ConditionalExpression conditionalExpression
? GetValueBufferIndex(conditionalExpression.IfTrue)
- : (int)((ConstantExpression)((MethodCallExpression)expression).Arguments[1]).Value;
+ : ((MethodCallExpression)expression).Arguments[1].GetConstantValue();
}
///
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
index ac691d0d4da..edfd357bd8b 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
@@ -79,7 +79,7 @@ protected override QueryableMethodTranslatingExpressionVisitor CreateSubqueryVis
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitMethodCall(MethodCallExpression methodCallExpression)
+ protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
if (methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Arguments.Count == 1
@@ -469,14 +469,15 @@ private static ShapedQueryExpression CreateShapedQueryExpressionStatic(IEntityTy
return newExpression;
}
- var newArguments = new Expression?[newExpression.Arguments.Count];
+ var newArguments = new Expression[newExpression.Arguments.Count];
for (var i = 0; i < newArguments.Length; i++)
{
- newArguments[i] = TranslateGroupingKey(newExpression.Arguments[i]);
- if (newArguments[i] == null)
+ var key = TranslateGroupingKey(newExpression.Arguments[i]);
+ if (key == null)
{
return null;
}
+ newArguments[i] = key;
}
return newExpression.Update(newArguments);
@@ -1053,9 +1054,9 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
Check.NotNull(source, nameof(source));
Check.NotNull(selector, nameof(selector));
- var innerParameter = Expression.Parameter(selector.ReturnType.TryGetSequenceType(), "i");
+ var innerParameter = Expression.Parameter(selector.ReturnType.GetSequenceType(), "i");
var resultSelector = Expression.Lambda(
- innerParameter, Expression.Parameter(source.Type.TryGetSequenceType()), innerParameter);
+ innerParameter, Expression.Parameter(source.Type.GetSequenceType()), innerParameter);
return TranslateSelectMany(source, selector, resultSelector);
}
@@ -1339,7 +1340,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
source = Visit(source);
return TryExpand(source, MemberIdentity.Create(navigationName))
- ?? methodCallExpression.Update(null, new[] { source, methodCallExpression.Arguments[1] });
+ ?? methodCallExpression.Update(null!, new[] { source, methodCallExpression.Arguments[1] });
}
if (methodCallExpression.TryGetEFPropertyArguments(out source, out navigationName))
@@ -1363,7 +1364,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
: base.VisitExtension(extensionExpression);
}
- private Expression? TryExpand(Expression source, MemberIdentity member)
+ private Expression? TryExpand(Expression? source, MemberIdentity member)
{
source = source.UnwrapTypeConversion(out var convertedType);
if (!(source is EntityShaperExpression entityShaperExpression))
@@ -1432,7 +1433,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
Expression.Equal(outerKey, innerKey))
: Expression.Equal(outerKey, innerKey);
- var correlationPredicate = _expressionTranslator.Translate(predicate);
+ var correlationPredicate = _expressionTranslator.Translate(predicate)!;
innerQueryExpression.UpdateServerQueryExpression(
Expression.Call(
EnumerableMethods.Where.MakeGenericMethod(innerQueryExpression.CurrentParameter.Type),
@@ -1479,9 +1480,9 @@ protected override Expression VisitExtension(Expression extensionExpression)
: foreignKey.Properties,
makeNullable);
- var outerKeySelector = Expression.Lambda(_expressionTranslator.Translate(outerKey), _queryExpression.CurrentParameter);
+ var outerKeySelector = Expression.Lambda(_expressionTranslator.Translate(outerKey)!, _queryExpression.CurrentParameter);
var innerKeySelector = Expression.Lambda(
- _expressionTranslator.Translate(innerKey), innerQueryExpression.CurrentParameter);
+ _expressionTranslator.Translate(innerKey)!, innerQueryExpression.CurrentParameter);
(outerKeySelector, innerKeySelector) = AlignKeySelectorTypes(outerKeySelector, innerKeySelector);
innerShaper = _queryExpression.AddNavigationToWeakEntityType(
entityProjectionExpression, navigation, innerQueryExpression, outerKeySelector, innerKeySelector);
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs
index 06206af6b05..2c999dd5c37 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.cs
@@ -27,20 +27,16 @@ public CustomShaperCompilingExpressionVisitor(bool tracking)
}
private static readonly MethodInfo _includeReferenceMethodInfo
- = typeof(CustomShaperCompilingExpressionVisitor).GetTypeInfo()
- .GetDeclaredMethod(nameof(IncludeReference));
+ = typeof(CustomShaperCompilingExpressionVisitor).GetRequiredDeclaredMethod(nameof(IncludeReference));
private static readonly MethodInfo _includeCollectionMethodInfo
- = typeof(CustomShaperCompilingExpressionVisitor).GetTypeInfo()
- .GetDeclaredMethod(nameof(IncludeCollection));
+ = typeof(CustomShaperCompilingExpressionVisitor).GetRequiredDeclaredMethod(nameof(IncludeCollection));
private static readonly MethodInfo _materializeCollectionMethodInfo
- = typeof(CustomShaperCompilingExpressionVisitor).GetTypeInfo()
- .GetDeclaredMethod(nameof(MaterializeCollection));
+ = typeof(CustomShaperCompilingExpressionVisitor).GetRequiredDeclaredMethod(nameof(MaterializeCollection));
private static readonly MethodInfo _materializeSingleResultMethodInfo
- = typeof(CustomShaperCompilingExpressionVisitor).GetTypeInfo()
- .GetDeclaredMethod(nameof(MaterializeSingleResult));
+ = typeof(CustomShaperCompilingExpressionVisitor).GetRequiredDeclaredMethod(nameof(MaterializeSingleResult));
private static void IncludeReference(
QueryContext queryContext,
@@ -271,8 +267,7 @@ private static Expression AddToCollectionNavigation(
Expression.Constant(true));
private static readonly MethodInfo _collectionAccessorAddMethodInfo
- = typeof(IClrCollectionAccessor).GetTypeInfo()
- .GetDeclaredMethod(nameof(IClrCollectionAccessor.Add));
+ = typeof(IClrCollectionAccessor).GetRequiredDeclaredMethod(nameof(IClrCollectionAccessor.Add));
}
}
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.cs
index 4aa12a7672d..daeef79487c 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.InMemoryProjectionBindingRemovingExpressionVisitor.cs
@@ -41,10 +41,8 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
= ((IDictionary)GetProjectionIndex(queryExpression, projectionBindingExpression),
((InMemoryQueryExpression)projectionBindingExpression.QueryExpression).CurrentParameter);
- var updatedExpression = Expression.New(
- newExpression.Constructor,
- Expression.Constant(ValueBuffer.Empty),
- newExpression.Arguments[1]);
+ var updatedExpression = newExpression.Update(
+ new[] { Expression.Constant(ValueBuffer.Empty), newExpression.Arguments[1] });
return Expression.MakeBinary(ExpressionType.Assign, binaryExpression.Left, updatedExpression);
}
@@ -67,10 +65,10 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
if (methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod)
{
- var property = (IProperty?)((ConstantExpression)methodCallExpression.Arguments[2]).Value;
+ var property = methodCallExpression.Arguments[2].GetConstantValue();
var (indexMap, valueBuffer) =
_materializationContextBindings[
- (ParameterExpression)((MethodCallExpression)methodCallExpression.Arguments[0]).Object];
+ (ParameterExpression)((MethodCallExpression)methodCallExpression.Arguments[0]).Object!];
Check.DebugAssert(
property != null || methodCallExpression.Type.IsNullableType(), "Must read nullable value without property");
@@ -113,7 +111,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
&& methodCallExpression.Method.IsGenericMethod
&& methodCallExpression.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod)
{
- return (IPropertyBase)((ConstantExpression)methodCallExpression.Arguments[2]).Value;
+ return methodCallExpression.Arguments[2].GetConstantValue();
}
return null;
@@ -124,7 +122,7 @@ private object GetProjectionIndex(
ProjectionBindingExpression projectionBindingExpression)
{
return projectionBindingExpression.ProjectionMember != null
- ? ((ConstantExpression)queryExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember)).Value
+ ? queryExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember).GetConstantValue
- public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
+ public override long GetChars(int ordinal, long dataOffset, char[]? buffer, int bufferOffset, int length)
{
throw new NotSupportedException();
}
diff --git a/src/EFCore.Relational/Query/Internal/CollateTranslator.cs b/src/EFCore.Relational/Query/Internal/CollateTranslator.cs
index f43a3f6cb44..4f3ff2e0953 100644
--- a/src/EFCore.Relational/Query/Internal/CollateTranslator.cs
+++ b/src/EFCore.Relational/Query/Internal/CollateTranslator.cs
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -20,7 +21,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
public class CollateTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _methodInfo
- = typeof(RelationalDbFunctionsExtensions).GetMethod(nameof(RelationalDbFunctionsExtensions.Collate));
+ = typeof(RelationalDbFunctionsExtensions).GetRequiredMethod(nameof(RelationalDbFunctionsExtensions.Collate));
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore.Relational/Query/Internal/EnumHasFlagTranslator.cs b/src/EFCore.Relational/Query/Internal/EnumHasFlagTranslator.cs
index a382c5f3e56..321addb22aa 100644
--- a/src/EFCore.Relational/Query/Internal/EnumHasFlagTranslator.cs
+++ b/src/EFCore.Relational/Query/Internal/EnumHasFlagTranslator.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
public class EnumHasFlagTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _methodInfo
- = typeof(Enum).GetRuntimeMethod(nameof(Enum.HasFlag), new[] { typeof(Enum) });
+ = typeof(Enum).GetRequiredRuntimeMethod(nameof(Enum.HasFlag), new[] { typeof(Enum) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs
index 71bcc951e79..d36d2774288 100644
--- a/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs
@@ -11,6 +11,7 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -31,7 +32,7 @@ private readonly IDictionary _visitedFromSqlExpre
private readonly IRelationalTypeMappingSource _typeMappingSource;
private readonly IParameterNameGeneratorFactory _parameterNameGeneratorFactory;
- private IReadOnlyDictionary _parametersValues;
+ private IReadOnlyDictionary _parametersValues;
private ParameterNameGenerator _parameterNameGenerator;
private bool _canCache;
@@ -61,7 +62,7 @@ public FromSqlParameterExpandingExpressionVisitor(
///
public virtual SelectExpression Expand(
[NotNull] SelectExpression selectExpression,
- [NotNull] IReadOnlyDictionary parameterValues,
+ [NotNull] IReadOnlyDictionary parameterValues,
out bool canCache)
{
Check.NotNull(selectExpression, nameof(selectExpression));
@@ -84,7 +85,8 @@ public virtual SelectExpression Expand(
/// 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 is FromSqlExpression fromSql)
{
@@ -93,7 +95,8 @@ public override Expression Visit(Expression expression)
switch (fromSql.Arguments)
{
case ParameterExpression parameterExpression:
- var parameterValues = (object[])_parametersValues[parameterExpression.Name];
+ // parameter value will never be null. It could be empty object[]
+ var parameterValues = (object[])_parametersValues[parameterExpression.Name!]!;
_canCache = false;
var subParameters = new List(parameterValues.Length);
@@ -132,8 +135,8 @@ public override Expression Visit(Expression expression)
break;
case ConstantExpression constantExpression:
- var existingValues = (object[])constantExpression.Value;
- var constantValues = new object[existingValues.Length];
+ var existingValues = constantExpression.GetConstantValue
-
-
-
-
diff --git a/src/EFCore.Sqlite.Core/Infrastructure/SpatialiteLoader.cs b/src/EFCore.Sqlite.Core/Infrastructure/SpatialiteLoader.cs
index 311d48ed35a..11784612f10 100644
--- a/src/EFCore.Sqlite.Core/Infrastructure/SpatialiteLoader.cs
+++ b/src/EFCore.Sqlite.Core/Infrastructure/SpatialiteLoader.cs
@@ -14,7 +14,6 @@
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyModel;
-using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment;
namespace Microsoft.EntityFrameworkCore.Infrastructure
{
@@ -127,11 +126,7 @@ private static void FindExtension()
if (hasDependencyContext)
{
var candidateAssets = new Dictionary<(string, string), int>();
-#if NET5_0
-#error Update to use RuntimeEnvironment.RuntimeIdentifier instead
-#endif
- var rid = AppContext.GetData("RUNTIME_IDENTIFIER") as string
- ?? RuntimeEnvironment.GetRuntimeIdentifier();
+ var rid = RuntimeInformation.RuntimeIdentifier;
var rids = DependencyContext.Default.RuntimeGraph.FirstOrDefault(g => g.Runtime == rid)?.Fallbacks.ToList()
?? new List();
rids.Insert(0, rid);
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteByteArrayMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteByteArrayMethodTranslator.cs
index eb42f8cbdb9..bc828f2c319 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteByteArrayMethodTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteByteArrayMethodTranslator.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
+using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -57,7 +58,7 @@ public SqliteByteArrayMethodTranslator([NotNull] ISqlExpressionFactory sqlExpres
var source = arguments[0];
var value = arguments[1] is SqlConstantExpression constantValue
- ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value }, source.TypeMapping)
+ ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, source.TypeMapping)
: _sqlExpressionFactory.Function(
"char",
new[] { arguments[1] },
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteCharMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteCharMethodTranslator.cs
index dc8f9934cf2..8adc6608897 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteCharMethodTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteCharMethodTranslator.cs
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -24,8 +25,8 @@ public class SqliteCharMethodTranslator : IMethodCallTranslator
{
private static readonly Dictionary _supportedMethods = new Dictionary
{
- { typeof(char).GetRuntimeMethod(nameof(char.ToLower), new[] { typeof(char) }), "lower" },
- { typeof(char).GetRuntimeMethod(nameof(char.ToUpper), new[] { typeof(char) }), "upper" }
+ { typeof(char).GetRequiredRuntimeMethod(nameof(char.ToLower), new[] { typeof(char) }), "lower" },
+ { typeof(char).GetRequiredRuntimeMethod(nameof(char.ToUpper), new[] { typeof(char) }), "upper" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteDateTimeAddTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteDateTimeAddTranslator.cs
index f96bee31277..8c473d5c381 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteDateTimeAddTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteDateTimeAddTranslator.cs
@@ -23,19 +23,19 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
public class SqliteDateTimeAddTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _addMilliseconds
- = typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMilliseconds), new[] { typeof(double) });
+ = typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddMilliseconds), new[] { typeof(double) });
private static readonly MethodInfo _addTicks
- = typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddTicks), new[] { typeof(long) });
+ = typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddTicks), new[] { typeof(long) });
private readonly Dictionary _methodInfoToUnitSuffix = new Dictionary
{
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddYears), new[] { typeof(int) }), " years" },
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMonths), new[] { typeof(int) }), " months" },
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddDays), new[] { typeof(double) }), " days" },
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddHours), new[] { typeof(double) }), " hours" },
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMinutes), new[] { typeof(double) }), " minutes" },
- { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddSeconds), new[] { typeof(double) }), " seconds" }
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddYears), new[] { typeof(int) }), " years" },
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddMonths), new[] { typeof(int) }), " months" },
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddDays), new[] { typeof(double) }), " days" },
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddHours), new[] { typeof(double) }), " hours" },
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddMinutes), new[] { typeof(double) }), " minutes" },
+ { typeof(DateTime).GetRequiredRuntimeMethod(nameof(DateTime.AddSeconds), new[] { typeof(double) }), " seconds" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs
index b3499545888..93fe90b8efc 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteMathTranslator.cs
@@ -26,32 +26,32 @@ public class SqliteMathTranslator : IMethodCallTranslator
{
private static readonly Dictionary _supportedMethods = new Dictionary
{
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(double) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(float) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(int) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(long) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(sbyte) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Abs), new[] { typeof(short) }), "abs" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(byte), typeof(byte) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(double), typeof(double) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(float), typeof(float) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(sbyte), typeof(sbyte) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(uint), typeof(uint) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Max), new[] { typeof(ushort), typeof(ushort) }), "max" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(byte), typeof(byte) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(double), typeof(double) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(float), typeof(float) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(sbyte), typeof(sbyte) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(uint), typeof(uint) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Min), new[] { typeof(ushort), typeof(ushort) }), "min" },
- { typeof(Math).GetMethod(nameof(Math.Round), new[] { typeof(double) }), "round" },
- { typeof(Math).GetMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }), "round" }
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(double) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(float) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(int) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(long) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(sbyte) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Abs), new[] { typeof(short) }), "abs" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(byte), typeof(byte) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(double), typeof(double) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(float), typeof(float) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(sbyte), typeof(sbyte) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(uint), typeof(uint) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Max), new[] { typeof(ushort), typeof(ushort) }), "max" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(byte), typeof(byte) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(double), typeof(double) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(float), typeof(float) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(sbyte), typeof(sbyte) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(uint), typeof(uint) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Min), new[] { typeof(ushort), typeof(ushort) }), "min" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Round), new[] { typeof(double) }), "round" },
+ { typeof(Math).GetRequiredMethod(nameof(Math.Round), new[] { typeof(double), typeof(int) }), "round" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
index 70335729590..016529664cf 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs
@@ -24,7 +24,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
public class SqliteRegexMethodTranslator : IMethodCallTranslator
{
private readonly static MethodInfo _regexIsMatchMethodInfo
- = typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new Type[] { typeof(string), typeof(string) });
+ = typeof(Regex).GetRequiredRuntimeMethod(nameof(Regex.IsMatch), new Type[] { typeof(string), typeof(string) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
index b7b48a1b881..eeb239a8bcc 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
@@ -95,7 +95,7 @@ public SqliteSqlTranslatingExpressionVisitor(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitUnary(UnaryExpression unaryExpression)
+ protected override Expression VisitUnary(UnaryExpression unaryExpression)
{
Check.NotNull(unaryExpression, nameof(unaryExpression));
@@ -109,13 +109,13 @@ public SqliteSqlTranslatingExpressionVisitor(
nullable: true,
argumentsPropagateNullability: new[] { true },
typeof(int))
- : null;
+ : QueryCompilationContext.NotTranslatedExpression;
}
var visitedExpression = base.VisitUnary(unaryExpression);
- if (visitedExpression == null)
+ if (visitedExpression == QueryCompilationContext.NotTranslatedExpression)
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (visitedExpression is SqlUnaryExpression sqlUnary
@@ -134,7 +134,7 @@ public SqliteSqlTranslatingExpressionVisitor(
if (operandType == typeof(TimeSpan))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
}
@@ -147,13 +147,13 @@ public SqliteSqlTranslatingExpressionVisitor(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- protected override Expression? VisitBinary(BinaryExpression binaryExpression)
+ protected override Expression VisitBinary(BinaryExpression binaryExpression)
{
Check.NotNull(binaryExpression, nameof(binaryExpression));
if (!(base.VisitBinary(binaryExpression) is SqlExpression visitedExpression))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
if (visitedExpression is SqlBinaryExpression sqlBinary)
@@ -185,7 +185,7 @@ public SqliteSqlTranslatingExpressionVisitor(
&& (restrictedTypes.Contains(GetProviderType(sqlBinary.Left))
|| restrictedTypes.Contains(GetProviderType(sqlBinary.Right))))
{
- return null;
+ return QueryCompilationContext.NotTranslatedExpression;
}
}
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteStringMethodTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteStringMethodTranslator.cs
index f2008e6f3d6..6ea758b686d 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteStringMethodTranslator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteStringMethodTranslator.cs
@@ -25,60 +25,60 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
public class SqliteStringMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _indexOfMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.IndexOf), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.IndexOf), new[] { typeof(string) });
private static readonly MethodInfo _replaceMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) });
private static readonly MethodInfo _toLowerMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.ToLower), Array.Empty());
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.ToLower), Array.Empty());
private static readonly MethodInfo _toUpperMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.ToUpper), Array.Empty());
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.ToUpper), Array.Empty());
private static readonly MethodInfo _substringMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.Substring), new[] { typeof(int), typeof(int) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Substring), new[] { typeof(int), typeof(int) });
private static readonly MethodInfo _isNullOrWhiteSpaceMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.IsNullOrWhiteSpace), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.IsNullOrWhiteSpace), new[] { typeof(string) });
// Method defined in netcoreapp2.0 only
private static readonly MethodInfo _trimStartMethodInfoWithoutArgs
- = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), Array.Empty());
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimStart), Array.Empty());
private static readonly MethodInfo _trimStartMethodInfoWithCharArg
- = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char) });
private static readonly MethodInfo _trimEndMethodInfoWithoutArgs
- = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), Array.Empty());
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimEnd), Array.Empty());
private static readonly MethodInfo _trimEndMethodInfoWithCharArg
- = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char) });
private static readonly MethodInfo _trimMethodInfoWithoutArgs
- = typeof(string).GetRuntimeMethod(nameof(string.Trim), Array.Empty());
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Trim), Array.Empty());
private static readonly MethodInfo _trimMethodInfoWithCharArg
- = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Trim), new[] { typeof(char) });
// Method defined in netstandard2.0
private static readonly MethodInfo _trimStartMethodInfoWithCharArrayArg
- = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char[]) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char[]) });
private static readonly MethodInfo _trimEndMethodInfoWithCharArrayArg
- = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char[]) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char[]) });
private static readonly MethodInfo _trimMethodInfoWithCharArrayArg
- = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char[]) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Trim), new[] { typeof(char[]) });
private static readonly MethodInfo _startsWithMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
private static readonly MethodInfo _containsMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.Contains), new[] { typeof(string) });
private static readonly MethodInfo _endsWithMethodInfo
- = typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
+ = typeof(string).GetRequiredRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
private static readonly MethodInfo _firstOrDefaultMethodInfoWithoutArgs
= typeof(Enumerable).GetRuntimeMethods().Single(
diff --git a/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj b/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
index a474ebe2109..e9bd6d09abc 100644
--- a/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
+++ b/src/EFCore.Sqlite.NTS/EFCore.Sqlite.NTS.csproj
@@ -5,7 +5,7 @@
Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite
Microsoft.EntityFrameworkCore.Sqlite
NetTopologySuite support for the SQLite database provider for Entity Framework Core.
- netstandard2.1
+ net5.0
3.6
true
$(PackageTags);SQLite;GIS;NTS;OGC;SpatiaLite
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs
index 3e6dbe39fef..8b88f462663 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMemberTranslator.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
///
public class SqliteGeometryCollectionMemberTranslator : IMemberTranslator
{
- private static readonly MemberInfo _count = typeof(GeometryCollection).GetRuntimeProperty(nameof(GeometryCollection.Count));
+ private static readonly MemberInfo _count = typeof(GeometryCollection).GetRequiredRuntimeProperty(nameof(GeometryCollection.Count));
private readonly ISqlExpressionFactory _sqlExpressionFactory;
///
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs
index 0e1e0ae2217..fa5bd14b8e3 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryCollectionMethodTranslator.cs
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
@@ -22,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
///
public class SqliteGeometryCollectionMethodTranslator : IMethodCallTranslator
{
- private static readonly MethodInfo _item = typeof(GeometryCollection).GetRuntimeProperty("Item").GetMethod;
+ private static readonly MethodInfo _item = typeof(GeometryCollection).GetRequiredRuntimeProperty("Item").GetMethod!;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
///
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs
index e6c226e7fea..6fbe946a546 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMemberTranslator.cs
@@ -25,24 +25,24 @@ public class SqliteGeometryMemberTranslator : IMemberTranslator
{
private static readonly IDictionary _memberToFunctionName = new Dictionary
{
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Area)), "Area" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Boundary)), "Boundary" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Centroid)), "Centroid" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Dimension)), "Dimension" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Envelope)), "Envelope" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.InteriorPoint)), "PointOnSurface" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.IsEmpty)), "IsEmpty" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.IsSimple)), "IsSimple" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.IsValid)), "IsValid" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.Length)), "GLength" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.NumGeometries)), "NumGeometries" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.NumPoints)), "NumPoints" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.PointOnSurface)), "PointOnSurface" },
- { typeof(Geometry).GetRuntimeProperty(nameof(Geometry.SRID)), "SRID" }
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Area)), "Area" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Boundary)), "Boundary" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Centroid)), "Centroid" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Dimension)), "Dimension" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Envelope)), "Envelope" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.InteriorPoint)), "PointOnSurface" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.IsEmpty)), "IsEmpty" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.IsSimple)), "IsSimple" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.IsValid)), "IsValid" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.Length)), "GLength" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.NumGeometries)), "NumGeometries" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.NumPoints)), "NumPoints" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.PointOnSurface)), "PointOnSurface" },
+ { typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.SRID)), "SRID" }
};
- private static readonly MemberInfo _geometryType = typeof(Geometry).GetRuntimeProperty(nameof(Geometry.GeometryType));
- private static readonly MemberInfo _ogcGeometryType = typeof(Geometry).GetRuntimeProperty(nameof(Geometry.OgcGeometryType));
+ private static readonly MemberInfo _geometryType = typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.GeometryType));
+ private static readonly MemberInfo _ogcGeometryType = typeof(Geometry).GetRequiredRuntimeProperty(nameof(Geometry.OgcGeometryType));
private readonly ISqlExpressionFactory _sqlExpressionFactory;
///
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs
index 85812dc7eb2..ed9e60d971d 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteGeometryMethodTranslator.cs
@@ -26,37 +26,37 @@ public class SqliteGeometryMethodTranslator : IMethodCallTranslator
{
private static readonly IDictionary _methodToFunctionName = new Dictionary
{
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.AsBinary), Type.EmptyTypes), "AsBinary" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.AsText), Type.EmptyTypes), "AsText" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Buffer), new[] { typeof(double) }), "Buffer" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Buffer), new[] { typeof(double), typeof(int) }), "Buffer" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Contains), new[] { typeof(Geometry) }), "Contains" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.ConvexHull), Type.EmptyTypes), "ConvexHull" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Crosses), new[] { typeof(Geometry) }), "Crosses" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.CoveredBy), new[] { typeof(Geometry) }), "CoveredBy" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Covers), new[] { typeof(Geometry) }), "Covers" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Difference), new[] { typeof(Geometry) }), "Difference" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Disjoint), new[] { typeof(Geometry) }), "Disjoint" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Distance), new[] { typeof(Geometry) }), "Distance" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.EqualsTopologically), new[] { typeof(Geometry) }), "Equals" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Intersection), new[] { typeof(Geometry) }), "Intersection" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Intersects), new[] { typeof(Geometry) }), "Intersects" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Overlaps), new[] { typeof(Geometry) }), "Overlaps" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Relate), new[] { typeof(Geometry), typeof(string) }), "Relate" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Reverse), Type.EmptyTypes), "ST_Reverse" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.SymmetricDifference), new[] { typeof(Geometry) }), "SymDifference" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.ToBinary), Type.EmptyTypes), "AsBinary" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.ToText), Type.EmptyTypes), "AsText" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Touches), new[] { typeof(Geometry) }), "Touches" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Union), Type.EmptyTypes), "UnaryUnion" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Union), new[] { typeof(Geometry) }), "GUnion" },
- { typeof(Geometry).GetRuntimeMethod(nameof(Geometry.Within), new[] { typeof(Geometry) }), "Within" }
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.AsBinary), Type.EmptyTypes), "AsBinary" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.AsText), Type.EmptyTypes), "AsText" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Buffer), new[] { typeof(double) }), "Buffer" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Buffer), new[] { typeof(double), typeof(int) }), "Buffer" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Contains), new[] { typeof(Geometry) }), "Contains" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.ConvexHull), Type.EmptyTypes), "ConvexHull" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Crosses), new[] { typeof(Geometry) }), "Crosses" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.CoveredBy), new[] { typeof(Geometry) }), "CoveredBy" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Covers), new[] { typeof(Geometry) }), "Covers" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Difference), new[] { typeof(Geometry) }), "Difference" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Disjoint), new[] { typeof(Geometry) }), "Disjoint" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Distance), new[] { typeof(Geometry) }), "Distance" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.EqualsTopologically), new[] { typeof(Geometry) }), "Equals" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Intersection), new[] { typeof(Geometry) }), "Intersection" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Intersects), new[] { typeof(Geometry) }), "Intersects" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Overlaps), new[] { typeof(Geometry) }), "Overlaps" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Relate), new[] { typeof(Geometry), typeof(string) }), "Relate" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Reverse), Type.EmptyTypes), "ST_Reverse" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.SymmetricDifference), new[] { typeof(Geometry) }), "SymDifference" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.ToBinary), Type.EmptyTypes), "AsBinary" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.ToText), Type.EmptyTypes), "AsText" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Touches), new[] { typeof(Geometry) }), "Touches" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Union), Type.EmptyTypes), "UnaryUnion" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Union), new[] { typeof(Geometry) }), "GUnion" },
+ { typeof(Geometry).GetRequiredRuntimeMethod(nameof(Geometry.Within), new[] { typeof(Geometry) }), "Within" }
};
- private static readonly MethodInfo _getGeometryN = typeof(Geometry).GetRuntimeMethod(
+ private static readonly MethodInfo _getGeometryN = typeof(Geometry).GetRequiredRuntimeMethod(
nameof(Geometry.GetGeometryN), new[] { typeof(int) });
- private static readonly MethodInfo _isWithinDistance = typeof(Geometry).GetRuntimeMethod(
+ private static readonly MethodInfo _isWithinDistance = typeof(Geometry).GetRequiredRuntimeMethod(
nameof(Geometry.IsWithinDistance), new[] { typeof(Geometry), typeof(double) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs
index e7bea4ecdc6..df3ca60fa80 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMemberTranslator.cs
@@ -26,11 +26,11 @@ public class SqliteLineStringMemberTranslator : IMemberTranslator
private static readonly IDictionary _memberToFunctionName
= new Dictionary
{
- { typeof(LineString).GetRuntimeProperty(nameof(LineString.Count)), "NumPoints" },
- { typeof(LineString).GetRuntimeProperty(nameof(LineString.EndPoint)), "EndPoint" },
- { typeof(LineString).GetRuntimeProperty(nameof(LineString.IsClosed)), "IsClosed" },
- { typeof(LineString).GetRuntimeProperty(nameof(LineString.IsRing)), "IsRing" },
- { typeof(LineString).GetRuntimeProperty(nameof(LineString.StartPoint)), "StartPoint" }
+ { typeof(LineString).GetRequiredRuntimeProperty(nameof(LineString.Count)), "NumPoints" },
+ { typeof(LineString).GetRequiredRuntimeProperty(nameof(LineString.EndPoint)), "EndPoint" },
+ { typeof(LineString).GetRequiredRuntimeProperty(nameof(LineString.IsClosed)), "IsClosed" },
+ { typeof(LineString).GetRequiredRuntimeProperty(nameof(LineString.IsRing)), "IsRing" },
+ { typeof(LineString).GetRequiredRuntimeProperty(nameof(LineString.StartPoint)), "StartPoint" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs
index ffbd0c129d7..899db3659ee 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteLineStringMethodTranslator.cs
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
@@ -23,7 +24,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
public class SqliteLineStringMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _getPointN
- = typeof(LineString).GetRuntimeMethod(nameof(LineString.GetPointN), new[] { typeof(int) });
+ = typeof(LineString).GetRequiredRuntimeMethod(nameof(LineString.GetPointN), new[] { typeof(int) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs
index 2dbdb9fbc48..5a5918e4504 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqliteMultiLineStringMemberTranslator.cs
@@ -22,7 +22,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
///
public class SqliteMultiLineStringMemberTranslator : IMemberTranslator
{
- private static readonly MemberInfo _isClosed = typeof(MultiLineString).GetRuntimeProperty(nameof(MultiLineString.IsClosed));
+ private static readonly MemberInfo _isClosed = typeof(MultiLineString).GetRequiredRuntimeProperty(nameof(MultiLineString.IsClosed));
private readonly ISqlExpressionFactory _sqlExpressionFactory;
///
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs
index 17738940ebf..e5a88d2908e 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePointMemberTranslator.cs
@@ -25,10 +25,10 @@ public class SqlitePointMemberTranslator : IMemberTranslator
{
private static readonly IDictionary _memberToFunctionName = new Dictionary
{
- { typeof(Point).GetRuntimeProperty(nameof(Point.M)), "M" },
- { typeof(Point).GetRuntimeProperty(nameof(Point.X)), "X" },
- { typeof(Point).GetRuntimeProperty(nameof(Point.Y)), "Y" },
- { typeof(Point).GetRuntimeProperty(nameof(Point.Z)), "Z" }
+ { typeof(Point).GetRequiredRuntimeProperty(nameof(Point.M)), "M" },
+ { typeof(Point).GetRequiredRuntimeProperty(nameof(Point.X)), "X" },
+ { typeof(Point).GetRequiredRuntimeProperty(nameof(Point.Y)), "Y" },
+ { typeof(Point).GetRequiredRuntimeProperty(nameof(Point.Z)), "Z" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs
index 9f78b3cd970..318dbddf8bc 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMemberTranslator.cs
@@ -26,8 +26,8 @@ public class SqlitePolygonMemberTranslator : IMemberTranslator
private static readonly IDictionary _memberToFunctionName
= new Dictionary
{
- { typeof(Polygon).GetRuntimeProperty(nameof(Polygon.ExteriorRing)), "ExteriorRing" },
- { typeof(Polygon).GetRuntimeProperty(nameof(Polygon.NumInteriorRings)), "NumInteriorRing" }
+ { typeof(Polygon).GetRequiredRuntimeProperty(nameof(Polygon.ExteriorRing)), "ExteriorRing" },
+ { typeof(Polygon).GetRequiredRuntimeProperty(nameof(Polygon.NumInteriorRings)), "NumInteriorRing" }
};
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs
index ad9ec68a0d9..7df6807abaa 100644
--- a/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs
+++ b/src/EFCore.Sqlite.NTS/Query/Internal/SqlitePolygonMethodTranslator.cs
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
@@ -23,7 +24,7 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
public class SqlitePolygonMethodTranslator : IMethodCallTranslator
{
private static readonly MethodInfo _getInteriorRingN
- = typeof(Polygon).GetRuntimeMethod(nameof(Polygon.GetInteriorRingN), new[] { typeof(int) });
+ = typeof(Polygon).GetRequiredRuntimeMethod(nameof(Polygon.GetInteriorRingN), new[] { typeof(int) });
private readonly ISqlExpressionFactory _sqlExpressionFactory;
diff --git a/src/EFCore.Sqlite.NTS/build/netstandard2.1/Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite.targets b/src/EFCore.Sqlite.NTS/build/net5.0/Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite.targets
similarity index 100%
rename from src/EFCore.Sqlite.NTS/build/netstandard2.1/Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite.targets
rename to src/EFCore.Sqlite.NTS/build/net5.0/Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite.targets
diff --git a/src/EFCore.Sqlite/EFCore.Sqlite.csproj b/src/EFCore.Sqlite/EFCore.Sqlite.csproj
index 93b90ef1463..90ae268eab0 100644
--- a/src/EFCore.Sqlite/EFCore.Sqlite.csproj
+++ b/src/EFCore.Sqlite/EFCore.Sqlite.csproj
@@ -4,7 +4,7 @@
SQLite database provider for Entity Framework Core.
- netstandard2.1
+ net5.0
3.6
Microsoft.EntityFrameworkCore.Sqlite
$(PackageTags);SQLite
diff --git a/src/EFCore.Sqlite/lib/netstandard2.1/_._ b/src/EFCore.Sqlite/lib/net5.0/_._
similarity index 100%
rename from src/EFCore.Sqlite/lib/netstandard2.1/_._
rename to src/EFCore.Sqlite/lib/net5.0/_._
diff --git a/src/EFCore.Tools/EFCore.Tools.nuspec b/src/EFCore.Tools/EFCore.Tools.nuspec
index f18c10abf7f..aaef2ea2023 100644
--- a/src/EFCore.Tools/EFCore.Tools.nuspec
+++ b/src/EFCore.Tools/EFCore.Tools.nuspec
@@ -5,7 +5,7 @@
$CommonMetadataElements$
3.6
-
+
diff --git a/src/EFCore.Tools/lib/netstandard2.1/_._ b/src/EFCore.Tools/lib/net5.0/_._
similarity index 100%
rename from src/EFCore.Tools/lib/netstandard2.1/_._
rename to src/EFCore.Tools/lib/net5.0/_._
diff --git a/src/EFCore/DbFunctions.cs b/src/EFCore/DbFunctions.cs
index 23389aa8c7c..7eff596ed09 100644
--- a/src/EFCore/DbFunctions.cs
+++ b/src/EFCore/DbFunctions.cs
@@ -26,7 +26,7 @@ private DbFunctions()
///
/// A string that represents the current object.
[EditorBrowsable(EditorBrowsableState.Never)]
- public override string ToString()
+ public override string? ToString()
=> base.ToString();
///
@@ -35,7 +35,7 @@ public override string ToString()
/// The object to compare with the current object.
/// if the specified object is equal to the current object; otherwise, .
[EditorBrowsable(EditorBrowsableState.Never)]
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> base.Equals(obj);
///
diff --git a/src/EFCore/EF.cs b/src/EFCore/EF.cs
index 6193201219f..df2f4ce54d7 100644
--- a/src/EFCore/EF.cs
+++ b/src/EFCore/EF.cs
@@ -19,7 +19,7 @@ namespace Microsoft.EntityFrameworkCore
public static partial class EF
{
internal static readonly MethodInfo PropertyMethod
- = typeof(EF).GetTypeInfo().GetDeclaredMethod(nameof(Property));
+ = typeof(EF).GetRequiredDeclaredMethod(nameof(Property));
///
///
diff --git a/src/EFCore/EFCore.csproj b/src/EFCore/EFCore.csproj
index 83758dd4145..18b8eb5278f 100644
--- a/src/EFCore/EFCore.csproj
+++ b/src/EFCore/EFCore.csproj
@@ -7,7 +7,7 @@ Commonly Used Types:
Microsoft.EntityFrameworkCore.DbContext
Microsoft.EntityFrameworkCore.DbSet
- netstandard2.1
+ net5.0
3.6
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore
diff --git a/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs b/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs
index 1462390ed6e..7d3cfae4928 100644
--- a/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs
+++ b/src/EFCore/Extensions/EntityFrameworkQueryableExtensions.cs
@@ -2646,7 +2646,7 @@ internal static readonly MethodInfo StringIncludeMethodInfo
///
public static IQueryable Include(
[NotNull] this IQueryable source,
- [NotNull] [NotParameterized] string navigationPropertyPath)
+ [NotNull][NotParameterized] string navigationPropertyPath)
where TEntity : class
{
Check.NotNull(source, nameof(source));
@@ -2669,7 +2669,7 @@ source.Provider is EntityQueryProvider
internal static readonly MethodInfo IgnoreAutoIncludesMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
- .GetTypeInfo().GetDeclaredMethod(nameof(IgnoreAutoIncludes));
+ .GetRequiredDeclaredMethod(nameof(IgnoreAutoIncludes));
///
/// Specifies that the current Entity Framework LINQ query should not have any
@@ -2702,7 +2702,7 @@ source.Provider is EntityQueryProvider
internal static readonly MethodInfo IgnoreQueryFiltersMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
- .GetTypeInfo().GetDeclaredMethod(nameof(IgnoreQueryFilters));
+ .GetRequiredDeclaredMethod(nameof(IgnoreQueryFilters));
///
/// Specifies that the current Entity Framework LINQ query should not have any
@@ -2738,7 +2738,7 @@ source.Provider is EntityQueryProvider
internal static readonly MethodInfo AsNoTrackingMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
- .GetTypeInfo().GetDeclaredMethod(nameof(AsNoTracking));
+ .GetRequiredDeclaredMethod(nameof(AsNoTracking));
///
///
@@ -2786,7 +2786,7 @@ source.Provider is EntityQueryProvider
internal static readonly MethodInfo AsNoTrackingWithIdentityResolutionMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
- .GetTypeInfo().GetDeclaredMethod(nameof(AsNoTrackingWithIdentityResolution));
+ .GetRequiredDeclaredMethod(nameof(AsNoTrackingWithIdentityResolution));
///
///
@@ -2914,7 +2914,7 @@ public static IQueryable AsTracking(
internal static readonly MethodInfo TagWithMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
- .GetTypeInfo().GetDeclaredMethod(nameof(TagWith));
+ .GetRequiredDeclaredMethod(nameof(TagWith));
///
/// Adds a tag to the collection of tags associated with an EF LINQ query. Tags are query annotations
@@ -2934,7 +2934,7 @@ internal static readonly MethodInfo TagWithMethodInfo
///
public static IQueryable TagWith(
[NotNull] this IQueryable source,
- [NotNull] [NotParameterized] string tag)
+ [NotNull][NotParameterized] string tag)
{
Check.NotNull(source, nameof(source));
Check.NotEmpty(tag, nameof(tag));
@@ -3037,6 +3037,7 @@ public static Task> ToDictionaryAsync(
[NotNull] this IQueryable source,
[NotNull] Func keySelector,
CancellationToken cancellationToken = default)
+ where TKey : notnull
=> ToDictionaryAsync(source, keySelector, e => e, comparer: null, cancellationToken);
///
@@ -3076,6 +3077,7 @@ public static Task> ToDictionaryAsync(
[NotNull] Func keySelector,
[NotNull] IEqualityComparer comparer,
CancellationToken cancellationToken = default)
+ where TKey : notnull
=> ToDictionaryAsync(source, keySelector, e => e, comparer, cancellationToken);
///
@@ -3117,6 +3119,7 @@ public static Task> ToDictionaryAsync keySelector,
[NotNull] Func elementSelector,
CancellationToken cancellationToken = default)
+ where TKey : notnull
=> ToDictionaryAsync(source, keySelector, elementSelector, comparer: null, cancellationToken);
///
@@ -3162,6 +3165,7 @@ public static async Task> ToDictionaryAsync elementSelector,
[CanBeNull] IEqualityComparer? comparer,
CancellationToken cancellationToken = default)
+ where TKey : notnull
{
Check.NotNull(source, nameof(source));
Check.NotNull(keySelector, nameof(keySelector));
diff --git a/src/EFCore/Extensions/Internal/ExpressionExtensions.cs b/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
index fd2d2efde87..182aa34dc12 100644
--- a/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
+++ b/src/EFCore/Extensions/Internal/ExpressionExtensions.cs
@@ -11,6 +11,7 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -48,7 +49,7 @@ public static Expression MakeHasDefaultValue(
return Expression.Not(
Expression.Call(
currentValueExpression,
- currentValueExpression.Type.GetMethod("get_HasValue")));
+ currentValueExpression.Type.GetRequiredMethod("get_HasValue")));
}
var property = propertyBase as IProperty;
@@ -122,10 +123,10 @@ var memberInfos
var memberInfos = new List();
MemberExpression? memberExpression;
-
+ var unwrappedExpression = RemoveTypeAs(RemoveConvert(memberAccessExpression));
do
{
- memberExpression = RemoveTypeAs(RemoveConvert(memberAccessExpression)) as MemberExpression;
+ memberExpression = unwrappedExpression as MemberExpression;
if (!(memberExpression?.Member is TMemberInfo memberInfo))
{
@@ -134,9 +135,9 @@ var memberInfos
memberInfos.Insert(0, memberInfo);
- memberAccessExpression = memberExpression.Expression;
+ unwrappedExpression = RemoveTypeAs(RemoveConvert(memberExpression.Expression));
}
- while (RemoveTypeAs(RemoveConvert(memberExpression.Expression)) != parameterExpression);
+ while (unwrappedExpression != parameterExpression);
return memberInfos;
}
@@ -195,7 +196,8 @@ public static bool IsLogicalNot([NotNull] this UnaryExpression sqlUnaryExpressio
&& (sqlUnaryExpression.Type == typeof(bool)
|| sqlUnaryExpression.Type == typeof(bool?));
- private static Expression RemoveConvert(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ private static Expression? RemoveConvert(Expression? expression)
{
if (expression is UnaryExpression unaryExpression
&& (expression.NodeType == ExpressionType.Convert
@@ -208,7 +210,7 @@ private static Expression RemoveConvert(Expression expression)
}
private static readonly MethodInfo _objectEqualsMethodInfo
- = typeof(object).GetRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) });
+ = typeof(object).GetRequiredRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) });
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Extensions/Internal/TypeExtensions.cs b/src/EFCore/Extensions/Internal/TypeExtensions.cs
index f88420267dd..86a25eef257 100644
--- a/src/EFCore/Extensions/Internal/TypeExtensions.cs
+++ b/src/EFCore/Extensions/Internal/TypeExtensions.cs
@@ -35,7 +35,7 @@ public static bool IsDefaultValue([NotNull] this Type type, [CanBeNull] object v
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public static FieldInfo GetFieldInfo([NotNull] this Type type, [NotNull] string fieldName)
+ public static FieldInfo? GetFieldInfo([NotNull] this Type type, [NotNull] string fieldName)
=> type.GetRuntimeFields().FirstOrDefault(f => f.Name == fieldName && !f.IsStatic);
///
diff --git a/src/EFCore/Extensions/ModelExtensions.cs b/src/EFCore/Extensions/ModelExtensions.cs
index 8b98f20c495..ebdf3e752fc 100644
--- a/src/EFCore/Extensions/ModelExtensions.cs
+++ b/src/EFCore/Extensions/ModelExtensions.cs
@@ -175,6 +175,7 @@ public static PropertyAccessMode GetPropertyAccessMode([NotNull] this IModel mod
public static bool IsIndexerMethod([NotNull] this IModel model, [NotNull] MethodInfo methodInfo)
=> !methodInfo.IsStatic
&& methodInfo.IsSpecialName
+ && methodInfo.DeclaringType != null
&& model.AsModel().FindIndexerPropertyInfo(methodInfo.DeclaringType) is PropertyInfo indexerProperty
&& (methodInfo == indexerProperty.GetMethod || methodInfo == indexerProperty.SetMethod);
diff --git a/src/EFCore/Extensions/PropertyExtensions.cs b/src/EFCore/Extensions/PropertyExtensions.cs
index a497f85e751..3931a0f811f 100644
--- a/src/EFCore/Extensions/PropertyExtensions.cs
+++ b/src/EFCore/Extensions/PropertyExtensions.cs
@@ -376,12 +376,12 @@ public NullableComparer(IEqualityComparer comparer)
_comparer = comparer;
}
- public bool Equals(TNullableKey x, TNullableKey y)
+ public bool Equals(TNullableKey? x, TNullableKey? y)
=> (x == null && y == null)
|| (x != null && y != null && _comparer.Equals(x, y));
public int GetHashCode(TNullableKey obj)
- => _comparer.GetHashCode(obj);
+ => obj is null ? 0 : _comparer.GetHashCode(obj);
}
///
diff --git a/src/EFCore/Infrastructure/Annotatable.cs b/src/EFCore/Infrastructure/Annotatable.cs
index ecfad36c733..8676405f79e 100644
--- a/src/EFCore/Infrastructure/Annotatable.cs
+++ b/src/EFCore/Infrastructure/Annotatable.cs
@@ -153,7 +153,6 @@ public virtual void SetAnnotation(string name, object? value)
return null;
}
- // TODO-NULLABLE: Put MemberNotNull on FindAnnotation when we target net5.0
_annotations!.Remove(name);
if (_annotations.Count == 0)
diff --git a/src/EFCore/Infrastructure/ExpressionExtensions.cs b/src/EFCore/Infrastructure/ExpressionExtensions.cs
index d5d9a9997e0..af70a95eb51 100644
--- a/src/EFCore/Infrastructure/ExpressionExtensions.cs
+++ b/src/EFCore/Infrastructure/ExpressionExtensions.cs
@@ -79,14 +79,15 @@ public static Expression Assign(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { memberExpression, valueExpression },
- null);
+ null)!;
}
return Expression.Assign(memberExpression, valueExpression);
}
private static readonly Type _assignBinaryExpressionType
- = typeof(Expression).Assembly.GetType("System.Linq.Expressions.AssignBinaryExpression");
+ // TODO-Nullable: Somethings are unexplainable
+ = typeof(Expression).Assembly.GetType("System.Linq.Expressions.AssignBinaryExpression", throwOnError: true)!;
///
/// If the given a method-call expression represents a call to , then this
@@ -105,7 +106,7 @@ public static bool TryGetEFPropertyArguments(
&& methodCallExpression.Arguments[1] is ConstantExpression propertyNameExpression)
{
entityExpression = methodCallExpression.Arguments[0];
- propertyName = (string)propertyNameExpression.Value;
+ propertyName = (string)propertyNameExpression.Value!;
return true;
}
@@ -131,8 +132,9 @@ public static bool TryGetIndexerArguments(
if (model.IsIndexerMethod(methodCallExpression.Method)
&& methodCallExpression.Arguments[0] is ConstantExpression propertyNameExpression)
{
- entityExpression = methodCallExpression.Object;
- propertyName = (string)propertyNameExpression.Value;
+ entityExpression = methodCallExpression.Object!;
+ propertyName = (string)propertyNameExpression.Value!;
+
return true;
}
@@ -194,7 +196,7 @@ public static bool TryGetIndexerArguments(
{
var propertyGetter = propertyInfo.GetMethod;
var interfaceMapping = parameterType.GetTypeInfo().GetRuntimeInterfaceMap(declaringType);
- var index = Array.FindIndex(interfaceMapping.InterfaceMethods, p => propertyGetter.Equals(p));
+ var index = Array.FindIndex(interfaceMapping.InterfaceMethods, p => p.Equals(propertyGetter));
var targetMethod = interfaceMapping.TargetMethods[index];
foreach (var runtimeProperty in parameterType.GetRuntimeProperties())
{
@@ -315,8 +317,7 @@ public static Expression CreateValueBufferReadValueExpression(
///
///
public static readonly MethodInfo ValueBufferTryReadValueMethod
- = typeof(ExpressionExtensions).GetTypeInfo()
- .GetDeclaredMethod(nameof(ValueBufferTryReadValue));
+ = typeof(ExpressionExtensions).GetRequiredDeclaredMethod(nameof(ValueBufferTryReadValue));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static TValue ValueBufferTryReadValue(
diff --git a/src/EFCore/Infrastructure/IndentedStringBuilder.cs b/src/EFCore/Infrastructure/IndentedStringBuilder.cs
index 708e994bdc9..133793a0718 100644
--- a/src/EFCore/Infrastructure/IndentedStringBuilder.cs
+++ b/src/EFCore/Infrastructure/IndentedStringBuilder.cs
@@ -94,7 +94,7 @@ public virtual IndentedStringBuilder AppendLines([NotNull] string value, bool sk
using (var reader = new StringReader(value))
{
var first = true;
- string line;
+ string? line;
while ((line = reader.ReadLine()) != null)
{
if (first)
diff --git a/src/EFCore/Infrastructure/MethodInfoExtensions.cs b/src/EFCore/Infrastructure/MethodInfoExtensions.cs
index e40e5fcbff8..8a77d38ff9c 100644
--- a/src/EFCore/Infrastructure/MethodInfoExtensions.cs
+++ b/src/EFCore/Infrastructure/MethodInfoExtensions.cs
@@ -19,7 +19,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure
///
public static class MethodInfoExtensions
{
- private static readonly string _efTypeName = typeof(EF).FullName;
+ private static readonly string _efTypeName = typeof(EF).FullName!;
///
/// Returns if the given method is .
diff --git a/src/EFCore/Metadata/Internal/EntityType.cs b/src/EFCore/Metadata/Internal/EntityType.cs
index 9e7d4856c2f..590adbc3e98 100644
--- a/src/EFCore/Metadata/Internal/EntityType.cs
+++ b/src/EFCore/Metadata/Internal/EntityType.cs
@@ -2953,7 +2953,7 @@ public override string OnTypeMemberIgnored(string name)
}
var data = new List>();
- var valueConverters = new Dictionary(StringComparer.Ordinal);
+ var valueConverters = new Dictionary(StringComparer.Ordinal);
var properties = GetProperties()
.Concat(GetNavigations())
.Concat(GetSkipNavigations())
diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs
index 461e029e780..b2717b0f31f 100644
--- a/src/EFCore/Metadata/Internal/Model.cs
+++ b/src/EFCore/Metadata/Internal/Model.cs
@@ -850,14 +850,16 @@ public virtual bool IsOwned([NotNull] Type type)
return null;
}
- while (type != null)
+ var currentType = type;
+
+ while (currentType != null)
{
- if (ownedTypes.TryGetValue(GetDisplayName(type), out var configurationSource))
+ if (ownedTypes.TryGetValue(GetDisplayName(currentType), out var configurationSource))
{
return configurationSource;
}
- type = type.BaseType;
+ currentType = currentType.BaseType;
}
return null;
diff --git a/src/EFCore/Metadata/Internal/Navigation.cs b/src/EFCore/Metadata/Internal/Navigation.cs
index 5fad9adfc7f..157def6b4e8 100644
--- a/src/EFCore/Metadata/Internal/Navigation.cs
+++ b/src/EFCore/Metadata/Internal/Navigation.cs
@@ -211,7 +211,7 @@ public static bool IsCompatible(
bool? shouldBeCollection,
bool shouldThrow)
{
- if (!navigationProperty.DeclaringType.IsAssignableFrom(sourceClrType))
+ if (!navigationProperty.DeclaringType!.IsAssignableFrom(sourceClrType))
{
if (shouldThrow)
{
diff --git a/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs b/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs
index 5d9294020aa..bdb62973869 100644
--- a/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs
+++ b/src/EFCore/Metadata/Internal/PropertyAccessorsFactory.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
@@ -40,6 +41,7 @@ private static readonly MethodInfo _genericCreate
private static PropertyAccessors CreateGeneric(IPropertyBase propertyBase)
{
var property = propertyBase as IProperty;
+
return new PropertyAccessors(
CreateCurrentValueGetter(propertyBase, useStoreGeneratedValues: true),
CreateCurrentValueGetter(propertyBase, useStoreGeneratedValues: false),
diff --git a/src/EFCore/Metadata/Internal/PropertyBase.cs b/src/EFCore/Metadata/Internal/PropertyBase.cs
index 7ed4b1e0842..52172bec9a3 100644
--- a/src/EFCore/Metadata/Internal/PropertyBase.cs
+++ b/src/EFCore/Metadata/Internal/PropertyBase.cs
@@ -154,14 +154,12 @@ public virtual void SetConfigurationSource(ConfigurationSource configurationSour
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public static FieldInfo GetFieldInfo(
+ public static FieldInfo? GetFieldInfo(
[NotNull] string fieldName,
[NotNull] TypeBase type,
- [CanBeNull] string propertyName,
+ [NotNull] string propertyName,
bool shouldThrow)
{
- Check.DebugAssert(propertyName != null || !shouldThrow, "propertyName is null");
-
if (!type.GetRuntimeFields()!.TryGetValue(fieldName, out var fieldInfo)
&& shouldThrow)
{
@@ -252,7 +250,7 @@ public static bool IsCompatible(
Check.DebugAssert(propertyName != null || !shouldThrow, "propertyName is null");
if (entityType == null
- || !fieldInfo.DeclaringType.IsAssignableFrom(entityType))
+ || !fieldInfo.DeclaringType!.IsAssignableFrom(entityType))
{
if (shouldThrow)
{
@@ -396,7 +394,7 @@ public virtual IComparer CurrentValueComparer
ref _currentValueComparer, this, p => new CurrentValueComparerFactory().Create(p));
private static readonly MethodInfo _containsKeyMethod =
- typeof(IDictionary).GetMethod(nameof(IDictionary.ContainsKey));
+ typeof(IDictionary).GetRequiredMethod(nameof(IDictionary.ContainsKey), new[] { typeof(string) });
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Metadata/Internal/SkipNavigationComparer.cs b/src/EFCore/Metadata/Internal/SkipNavigationComparer.cs
index e822e23a782..61f5d21eb39 100644
--- a/src/EFCore/Metadata/Internal/SkipNavigationComparer.cs
+++ b/src/EFCore/Metadata/Internal/SkipNavigationComparer.cs
@@ -34,11 +34,15 @@ private SkipNavigationComparer()
/// 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 int Compare(SkipNavigation x, SkipNavigation y)
- {
- var result = StringComparer.Ordinal.Compare(x.Name, y.Name);
-
- return result != 0 ? result : EntityTypeFullNameComparer.Instance.Compare(x.DeclaringEntityType, y.DeclaringEntityType);
- }
+ public int Compare(SkipNavigation? x, SkipNavigation? y)
+ => (x, y) switch
+ {
+ (not null, null) => 1,
+ (null, not null) => -1,
+ (null, null) => 0,
+ (not null, not null) => StringComparer.Ordinal.Compare(x!.Name, y!.Name) is var compare && compare != 0
+ ? compare
+ : EntityTypeFullNameComparer.Instance.Compare(x.DeclaringEntityType, y.DeclaringEntityType)
+ };
}
}
diff --git a/src/EFCore/Query/EntityShaperExpression.cs b/src/EFCore/Query/EntityShaperExpression.cs
index 09ac90e8c40..8bca1cc2074 100644
--- a/src/EFCore/Query/EntityShaperExpression.cs
+++ b/src/EFCore/Query/EntityShaperExpression.cs
@@ -31,8 +31,7 @@ namespace Microsoft.EntityFrameworkCore.Query
public class EntityShaperExpression : Expression, IPrintableExpression
{
private static readonly MethodInfo _createUnableToDiscriminateException
- = typeof(EntityShaperExpression).GetTypeInfo()
- .GetDeclaredMethod(nameof(CreateUnableToDiscriminateException));
+ = typeof(EntityShaperExpression).GetRequiredDeclaredMethod(nameof(CreateUnableToDiscriminateException));
[UsedImplicitly]
private static Exception CreateUnableToDiscriminateException(IEntityType entityType, object discriminator)
@@ -268,7 +267,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
expressionPrinter.AppendLine(nameof(EntityShaperExpression) + ": ");
using (expressionPrinter.Indent())
{
- expressionPrinter.AppendLine(EntityType.ToString());
+ expressionPrinter.AppendLine(EntityType.Name);
expressionPrinter.AppendLine(nameof(ValueBufferExpression) + ": ");
using (expressionPrinter.Indent())
{
diff --git a/src/EFCore/Query/EvaluatableExpressionFilter.cs b/src/EFCore/Query/EvaluatableExpressionFilter.cs
index 29e1ca767d9..bffec2e8662 100644
--- a/src/EFCore/Query/EvaluatableExpressionFilter.cs
+++ b/src/EFCore/Query/EvaluatableExpressionFilter.cs
@@ -30,31 +30,31 @@ public class EvaluatableExpressionFilter : IEvaluatableExpressionFilter
// Hence we don't evaluate them. See issue#2069
private static readonly PropertyInfo _dateTimeNow
- = typeof(DateTime).GetTypeInfo().GetDeclaredProperty(nameof(DateTime.Now));
+ = typeof(DateTime).GetRequiredDeclaredProperty(nameof(DateTime.Now));
private static readonly PropertyInfo _dateTimeUtcNow
- = typeof(DateTime).GetTypeInfo().GetDeclaredProperty(nameof(DateTime.UtcNow));
+ = typeof(DateTime).GetRequiredDeclaredProperty(nameof(DateTime.UtcNow));
private static readonly PropertyInfo _dateTimeToday
- = typeof(DateTime).GetTypeInfo().GetDeclaredProperty(nameof(DateTime.Today));
+ = typeof(DateTime).GetRequiredDeclaredProperty(nameof(DateTime.Today));
private static readonly PropertyInfo _dateTimeOffsetNow
- = typeof(DateTimeOffset).GetTypeInfo().GetDeclaredProperty(nameof(DateTimeOffset.Now));
+ = typeof(DateTimeOffset).GetRequiredDeclaredProperty(nameof(DateTimeOffset.Now));
private static readonly PropertyInfo _dateTimeOffsetUtcNow
- = typeof(DateTimeOffset).GetTypeInfo().GetDeclaredProperty(nameof(DateTimeOffset.UtcNow));
+ = typeof(DateTimeOffset).GetRequiredDeclaredProperty(nameof(DateTimeOffset.UtcNow));
private static readonly MethodInfo _guidNewGuid
- = typeof(Guid).GetTypeInfo().GetDeclaredMethod(nameof(Guid.NewGuid));
+ = typeof(Guid).GetRequiredDeclaredMethod(nameof(Guid.NewGuid));
private static readonly MethodInfo _randomNextNoArgs
- = typeof(Random).GetRuntimeMethod(nameof(Random.Next), Array.Empty());
+ = typeof(Random).GetRequiredRuntimeMethod(nameof(Random.Next), Array.Empty());
private static readonly MethodInfo _randomNextOneArg
- = typeof(Random).GetRuntimeMethod(nameof(Random.Next), new[] { typeof(int) });
+ = typeof(Random).GetRequiredRuntimeMethod(nameof(Random.Next), new[] { typeof(int) });
private static readonly MethodInfo _randomNextTwoArgs
- = typeof(Random).GetRuntimeMethod(nameof(Random.Next), new[] { typeof(int), typeof(int) });
+ = typeof(Random).GetRequiredRuntimeMethod(nameof(Random.Next), new[] { typeof(int), typeof(int) });
///
///
diff --git a/src/EFCore/Query/ExpressionEqualityComparer.cs b/src/EFCore/Query/ExpressionEqualityComparer.cs
index f964780639c..2f6b34d1598 100644
--- a/src/EFCore/Query/ExpressionEqualityComparer.cs
+++ b/src/EFCore/Query/ExpressionEqualityComparer.cs
@@ -18,7 +18,7 @@ namespace Microsoft.EntityFrameworkCore.Query
///
/// A comparer which implements for .
///
- public sealed class ExpressionEqualityComparer : IEqualityComparer
+ public sealed class ExpressionEqualityComparer : IEqualityComparer
{
///
/// Creates a new .
@@ -218,7 +218,7 @@ public int GetHashCode(Expression obj)
return hash.ToHashCode();
- void AddToHashIfNotNull(object t)
+ void AddToHashIfNotNull(object? t)
{
if (t != null)
{
@@ -226,7 +226,7 @@ void AddToHashIfNotNull(object t)
}
}
- void AddExpressionToHashIfNotNull(Expression t)
+ void AddExpressionToHashIfNotNull(Expression? t)
{
if (t != null)
{
@@ -286,14 +286,14 @@ void AddMemberBindingsToHash(IReadOnlyList memberBindings)
/// The left expression.
/// The right expression.
/// if the expressions are equal, otherwise.
- public bool Equals(Expression x, Expression y)
+ public bool Equals(Expression? x, Expression? y)
=> new ExpressionComparer().Compare(x, y);
private struct ExpressionComparer
{
private Dictionary _parameterScope;
- public bool Compare(Expression left, Expression right)
+ public bool Compare(Expression? left, Expression? right)
{
if (left == right)
{
@@ -512,7 +512,7 @@ private bool CompareExpressionList(IReadOnlyList a, IReadOnlyList a, IReadOnlyList b)
+ private bool CompareMemberList(IReadOnlyList? a, IReadOnlyList? b)
{
if (ReferenceEquals(a, b))
{
diff --git a/src/EFCore/Query/ExpressionPrinter.cs b/src/EFCore/Query/ExpressionPrinter.cs
index 38f8cdfe66a..1d63c1d5482 100644
--- a/src/EFCore/Query/ExpressionPrinter.cs
+++ b/src/EFCore/Query/ExpressionPrinter.cs
@@ -37,7 +37,7 @@ public class ExpressionPrinter : ExpressionVisitor
};
private readonly IndentedStringBuilder _stringBuilder;
- private readonly Dictionary _parametersInScope;
+ private readonly Dictionary _parametersInScope;
private readonly List _namelessParameters;
private readonly List _encounteredParameters;
@@ -69,7 +69,7 @@ public class ExpressionPrinter : ExpressionVisitor
public ExpressionPrinter()
{
_stringBuilder = new IndentedStringBuilder();
- _parametersInScope = new Dictionary();
+ _parametersInScope = new Dictionary();
_namelessParameters = new List();
_encounteredParameters = new List();
}
@@ -457,7 +457,7 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio
return constantExpression;
}
- private void Print(object value)
+ private void Print(object? value)
{
if (value is IEnumerable enumerable
&& !(value is string))
@@ -494,7 +494,7 @@ private void Print(object value)
stringValue = $@"""{stringValue}""";
}
- _stringBuilder.Append(stringValue);
+ _stringBuilder.Append(stringValue ?? "Unknown");
}
///
@@ -590,7 +590,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
else
{
// ReSharper disable once PossibleNullReferenceException
- _stringBuilder.Append(memberExpression.Member.DeclaringType.Name);
+ _stringBuilder.Append(memberExpression.Member.DeclaringType?.Name ?? "MethodWithoutDeclaringType");
}
_stringBuilder.Append("." + memberExpression.Member.Name);
@@ -699,7 +699,7 @@ var argumentNames
? extensionMethod
? method.GetParameters().Skip(1).Select(p => p.Name).ToList()
: method.GetParameters().Select(p => p.Name).ToList()
- : new List();
+ : new List();
IDisposable? indent = null;
@@ -880,12 +880,12 @@ protected override Expression VisitParameter(ParameterExpression parameterExpres
if (Verbose)
{
Append("(Unhandled parameter: ");
- Append(parameterExpression.Name);
+ Append(parameterExpression.Name ?? "NoNameParameter");
Append(")");
}
else
{
- Append(parameterExpression.Name);
+ Append(parameterExpression.Name ?? "NoNameParameter");
}
}
diff --git a/src/EFCore/Query/Internal/EntityMaterializerSource.cs b/src/EFCore/Query/Internal/EntityMaterializerSource.cs
index 872a61e1e47..99f35addede 100644
--- a/src/EFCore/Query/Internal/EntityMaterializerSource.cs
+++ b/src/EFCore/Query/Internal/EntityMaterializerSource.cs
@@ -151,9 +151,8 @@ static Expression CreateMemberAssignment(Expression parameter, MemberInfo member
private ConcurrentDictionary> Materializers
=> LazyInitializer.EnsureInitialized(
- // TODO-NULLABLE: LazyInitializer not yet null-annotated in netstandard2.1, can remove bang after targeting net5.0
ref _materializers,
- () => new ConcurrentDictionary>())!;
+ () => new ConcurrentDictionary>());
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Query/Internal/EntityQueryProvider.cs b/src/EFCore/Query/Internal/EntityQueryProvider.cs
index d7f0607ec25..75d68027aa6 100644
--- a/src/EFCore/Query/Internal/EntityQueryProvider.cs
+++ b/src/EFCore/Query/Internal/EntityQueryProvider.cs
@@ -69,7 +69,7 @@ public virtual IQueryable CreateQuery(Expression expression)
public virtual IQueryable CreateQuery(Expression expression)
=> (IQueryable)_genericCreateQueryMethod
.MakeGenericMethod(expression.Type.GetSequenceType())
- .Invoke(this, new object[] { expression });
+ .Invoke(this, new object[] { expression })!;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -88,7 +88,7 @@ public virtual TResult Execute(Expression expression)
///
public virtual object Execute(Expression expression)
=> _genericExecuteMethod.MakeGenericMethod(expression.Type)
- .Invoke(_queryCompiler, new object[] { expression });
+ .Invoke(_queryCompiler, new object[] { expression })!;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/src/EFCore/Query/Internal/IParameterValues.cs b/src/EFCore/Query/Internal/IParameterValues.cs
index 25ff48999f3..2ea64ac4388 100644
--- a/src/EFCore/Query/Internal/IParameterValues.cs
+++ b/src/EFCore/Query/Internal/IParameterValues.cs
@@ -22,7 +22,7 @@ public interface IParameterValues
/// 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.
///
- IReadOnlyDictionary ParameterValues { get; }
+ IReadOnlyDictionary ParameterValues { get; }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -30,6 +30,6 @@ public interface IParameterValues
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- void AddParameter([NotNull] string name, [CanBeNull] object value);
+ void AddParameter([NotNull] string name, [CanBeNull] object? value);
}
}
diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
index 083b991507d..ea94b338492 100644
--- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
+++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs
@@ -27,7 +27,7 @@ public partial class NavigationExpandingExpressionVisitor
private class ExpandingExpressionVisitor : ExpressionVisitor
{
private static readonly MethodInfo _objectEqualsMethodInfo
- = typeof(object).GetRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) });
+ = typeof(object).GetRequiredRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) });
private readonly NavigationExpandingExpressionVisitor _navigationExpandingExpressionVisitor;
private readonly NavigationExpansionExpression _source;
@@ -87,7 +87,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
{
source = Visit(source);
return TryExpandNavigation(source, MemberIdentity.Create(navigationName))
- ?? methodCallExpression.Update(null, new[] { source, methodCallExpression.Arguments[1] });
+ // TODO-Nullable bug
+ ?? methodCallExpression.Update(null!, new[] { source, methodCallExpression.Arguments[1] });
}
if (methodCallExpression.TryGetIndexerArguments(Model, out source, out navigationName))
@@ -100,8 +101,13 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return base.VisitMethodCall(methodCallExpression);
}
- private Expression? TryExpandNavigation(Expression root, MemberIdentity memberIdentity)
+ private Expression? TryExpandNavigation(Expression? root, MemberIdentity memberIdentity)
{
+ if (root == null)
+ {
+ return null;
+ }
+
var innerExpression = root.UnwrapTypeConversion(out var convertedType);
if (UnwrapEntityReference(innerExpression) is EntityReference entityReference)
{
@@ -163,7 +169,7 @@ protected Expression ExpandNavigation(
ownedExpansion = new OwnedNavigationReference(root, navigation, ownedEntityReference);
if (navigation.IsCollection)
{
- var elementType = ownedExpansion.Type.TryGetSequenceType();
+ var elementType = ownedExpansion.Type.GetSequenceType();
var subquery = Expression.Call(
QueryableMethods.AsQueryable.MakeGenericMethod(elementType),
ownedExpansion);
@@ -431,13 +437,14 @@ outerKey is NewArrayExpression newArrayExpression
var resultSelectorInnerParameter = Expression.Parameter(innerSource.SourceElementType, "i");
var resultType = TransparentIdentifierFactory.Create(_source.SourceElementType, innerSource.SourceElementType);
- var transparentIdentifierOuterMemberInfo = resultType.GetTypeInfo().GetDeclaredField("Outer");
- var transparentIdentifierInnerMemberInfo = resultType.GetTypeInfo().GetDeclaredField("Inner");
+ var transparentIdentifierOuterMemberInfo = resultType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var transparentIdentifierInnerMemberInfo = resultType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var resultSelector = Expression.Lambda(
Expression.New(
resultType.GetConstructors().Single(),
- new[] { resultSelectorOuterParameter, resultSelectorInnerParameter }, transparentIdentifierOuterMemberInfo,
+ new[] { resultSelectorOuterParameter, resultSelectorInnerParameter },
+ transparentIdentifierOuterMemberInfo,
transparentIdentifierInnerMemberInfo),
resultSelectorOuterParameter,
resultSelectorInnerParameter);
@@ -487,7 +494,7 @@ private static Expression AddConvertToObject(Expression expression)
private sealed class IncludeExpandingExpressionVisitor : ExpandingExpressionVisitor
{
private static readonly MethodInfo _fetchJoinEntityMethodInfo =
- typeof(IncludeExpandingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(FetchJoinEntity));
+ typeof(IncludeExpandingExpressionVisitor).GetRequiredDeclaredMethod(nameof(FetchJoinEntity));
private readonly bool _queryStateManager;
private readonly bool _ignoreAutoIncludes;
@@ -542,25 +549,28 @@ protected override Expression VisitMember(MemberExpression memberExpression)
{
Check.NotNull(memberExpression, nameof(memberExpression));
- var innerExpression = memberExpression.Expression.UnwrapTypeConversion(out var convertedType);
- if (UnwrapEntityReference(innerExpression) is EntityReference entityReference)
+ if (memberExpression.Expression != null)
{
- // If it is mapped property then, it would get converted to a column so we don't need to expand includes.
- var entityType = entityReference.EntityType;
- if (convertedType != null)
+ var innerExpression = memberExpression.Expression.UnwrapTypeConversion(out var convertedType);
+ if (UnwrapEntityReference(innerExpression) is EntityReference entityReference)
{
- entityType = entityType.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
- .FirstOrDefault(et => et.ClrType == convertedType);
- if (entityType == null)
+ // If it is mapped property then, it would get converted to a column so we don't need to expand includes.
+ var entityType = entityReference.EntityType;
+ if (convertedType != null)
{
- return base.VisitMember(memberExpression);
+ entityType = entityType.GetAllBaseTypes().Concat(entityType.GetDerivedTypesInclusive())
+ .FirstOrDefault(et => et.ClrType == convertedType);
+ if (entityType == null)
+ {
+ return base.VisitMember(memberExpression);
+ }
}
- }
- var property = entityType.FindProperty(memberExpression.Member);
- if (property != null)
- {
- return memberExpression;
+ var property = entityType.FindProperty(memberExpression.Member);
+ if (property != null)
+ {
+ return memberExpression;
+ }
}
}
@@ -627,7 +637,7 @@ private bool ReconstructAnonymousType(
for (var i = 0; i < newExpression.Arguments.Count; i++)
{
var argument = newExpression.Arguments[i];
- var newRoot = Expression.MakeMemberAccess(currentRoot, newExpression.Members[i]);
+ var newRoot = Expression.MakeMemberAccess(currentRoot, newExpression.Members![i]);
if (argument is EntityReference entityReference)
{
changed = true;
@@ -704,7 +714,7 @@ private Expression ExpandIncludesHelper(Expression root, EntityReference entityR
&& entityReference.EntityType.IsAssignableFrom(navigationBase.DeclaringEntityType))
{
converted = true;
- convertedRoot = Expression.Convert(root, navigationBase.DeclaringEntityType.ClrType);
+ convertedRoot = Expression.Convert(root, navigationBase.DeclaringEntityType.ClrType!);
}
var included = navigationBase switch
@@ -774,14 +784,15 @@ private Expression ExpandIncludesHelper(Expression root, EntityReference entityR
targetParameter));
subquery = joinMethodCallExpression.Update(
- null, joinMethodCallExpression.Arguments.Take(4).Append(newResultSelector));
+ // TODO-Nullable bug
+ null!, joinMethodCallExpression.Arguments.Take(4).Append(newResultSelector));
}
else
{
var resultType = TransparentIdentifierFactory.Create(joinParameter.Type, targetParameter.Type);
- var transparentIdentifierOuterMemberInfo = resultType.GetTypeInfo().GetDeclaredField("Outer");
- var transparentIdentifierInnerMemberInfo = resultType.GetTypeInfo().GetDeclaredField("Inner");
+ var transparentIdentifierOuterMemberInfo = resultType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var transparentIdentifierInnerMemberInfo = resultType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var newResultSelector = Expression.Quote(
Expression.Lambda(
@@ -896,7 +907,8 @@ public PendingSelectorExpandingExpressionVisitor(
_applyIncludes = applyIncludes;
}
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression is NavigationExpansionExpression navigationExpansionExpression)
{
@@ -921,7 +933,8 @@ public override Expression Visit(Expression expression)
///
private sealed class ReducingExpressionVisitor : ExpressionVisitor
{
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
switch (expression)
{
@@ -954,7 +967,7 @@ public override Expression Visit(Expression expression)
{
result = Expression.Call(
navigationExpansionExpression.CardinalityReducingGenericMethodInfo.MakeGenericMethod(
- result.Type.TryGetSequenceType()),
+ result.Type.GetSequenceType()),
result);
}
@@ -988,7 +1001,8 @@ public override Expression Visit(Expression expression)
///
private sealed class EntityReferenceOptionalMarkingExpressionVisitor : ExpressionVisitor
{
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression is EntityReference entityReference)
{
@@ -1130,7 +1144,8 @@ private Expression ProcessNavigationPath(Expression expression)
{
switch (expression)
{
- case MemberExpression memberExpression:
+ case MemberExpression memberExpression
+ when memberExpression.Expression != null:
var innerExpression = ProcessNavigationPath(memberExpression.Expression);
if (innerExpression is NavigationDataExpression navigationDataExpression
&& navigationDataExpression.EntityType != null)
diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
index cc0a59537ce..f9724a98f4f 100644
--- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs
@@ -13,6 +13,7 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
+using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -27,9 +28,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
public partial class NavigationExpandingExpressionVisitor : ExpressionVisitor
{
private static readonly PropertyInfo _queryContextContextPropertyInfo
- = typeof(QueryContext)
- .GetTypeInfo()
- .GetDeclaredProperty(nameof(QueryContext.Context));
+ = typeof(QueryContext).GetRequiredDeclaredProperty(nameof(QueryContext.Context));
private static readonly Dictionary _predicateLessMethodInfo = new Dictionary
{
@@ -125,7 +124,7 @@ public virtual Expression Expand([NotNull] Expression query)
foreach (var parameterValue in _parameters.ParameterValues)
{
- var lambda = (LambdaExpression)parameterValue.Value;
+ var lambda = (LambdaExpression)parameterValue.Value!;
var remappedLambdaBody = ReplacingExpressionVisitor.Replace(
lambda.Parameters[0],
dbContextOnQueryContextPropertyAccess,
@@ -206,6 +205,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
// Convert ICollection.Count to Count()
if (memberExpression.Expression != null
+ && innerExpression != null
&& memberExpression.Member.Name == nameof(ICollection.Count)
&& memberExpression.Expression.Type.GetInterfaces().Append(memberExpression.Expression.Type)
.Any(e => e.IsGenericType && e.GetGenericTypeDefinition() == typeof(ICollection<>)))
@@ -216,7 +216,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
{
return Visit(
Expression.Call(
- QueryableMethods.CountWithoutPredicate.MakeGenericMethod(innerQueryable.Type.TryGetSequenceType()),
+ QueryableMethods.CountWithoutPredicate.MakeGenericMethod(innerQueryable.Type.GetSequenceType()),
innerQueryable));
}
}
@@ -255,7 +255,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
|| method.DeclaringType == typeof(EntityFrameworkQueryableExtensions))
{
var genericMethod = method.IsGenericMethod ? method.GetGenericMethodDefinition() : null;
- var firstArgument = Visit(methodCallExpression.Arguments[0]);
+ // First argument is source
+ var firstArgument = Visit(methodCallExpression.Arguments[0])!;
if (firstArgument is NavigationExpansionExpression source)
{
if (source.PendingOrderings.Any()
@@ -454,8 +455,7 @@ when QueryableMethods.IsSumWithSelector(method):
return ProcessCastOfType(
source,
genericMethod,
- // Known to be sequence type
- methodCallExpression.Type.TryGetSequenceType()!);
+ methodCallExpression.Type.GetSequenceType());
case nameof(EntityFrameworkQueryableExtensions.Include):
case nameof(EntityFrameworkQueryableExtensions.ThenInclude):
@@ -562,8 +562,8 @@ when QueryableMethods.IsSumWithSelector(method):
if (firstArgument.Type.TryGetElementType(typeof(IQueryable<>)) == null)
{
// firstArgument was not an queryable
- var visitedArguments = new[] { firstArgument }
- .Concat(methodCallExpression.Arguments.Skip(1).Select(Visit));
+ var visitedArguments = new [] { firstArgument }
+ .Concat(methodCallExpression.Arguments.Skip(1).Select(e => Visit(e)!));
return ConvertToEnumerable(method, visitedArguments);
}
@@ -577,7 +577,8 @@ when QueryableMethods.IsSumWithSelector(method):
|| method.GetGenericMethodDefinition() == EnumerableMethods.ToArray))
{
return methodCallExpression.Update(
- null, new[] { UnwrapCollectionMaterialization(Visit(methodCallExpression.Arguments[0])) });
+ // TODO-Nullable bug
+ null!, new[] { UnwrapCollectionMaterialization(Visit(methodCallExpression.Arguments[0])) });
}
return ProcessUnknownMethod(methodCallExpression);
@@ -650,7 +651,7 @@ private Expression ProcessAverageMaxMinSum(NavigationExpansionExpression source,
if (method.GetGenericArguments().Length == 1)
{
// Min/Max without selector has 1 generic parameters
- method = method.MakeGenericMethod(queryable.Type.TryGetSequenceType());
+ method = method.MakeGenericMethod(queryable.Type.GetSequenceType());
}
return Expression.Call(method, queryable);
@@ -715,7 +716,7 @@ private Expression ProcessContains(NavigationExpansionExpression source, Express
source = (NavigationExpansionExpression)_pendingSelectorExpandingExpressionVisitor.Visit(source);
var queryable = Reduce(source);
- return Expression.Call(QueryableMethods.Contains.MakeGenericMethod(queryable.Type.TryGetSequenceType()), queryable, item);
+ return Expression.Call(QueryableMethods.Contains.MakeGenericMethod(queryable.Type.GetSequenceType()), queryable, item);
}
private NavigationExpansionExpression ProcessDefaultIfEmpty(NavigationExpansionExpression source)
@@ -745,7 +746,7 @@ private NavigationExpansionExpression ProcessDistinct(NavigationExpansionExpress
var newStructure = SnapshotExpression(source.PendingSelector);
var queryable = Reduce(source);
- var result = Expression.Call(genericMethod.MakeGenericMethod(queryable.Type.TryGetSequenceType()), queryable);
+ var result = Expression.Call(genericMethod.MakeGenericMethod(queryable.Type.GetSequenceType()), queryable);
var navigationTree = new NavigationTreeExpression(newStructure);
var parameterName = GetParameterName("e");
@@ -820,7 +821,7 @@ private NavigationExpansionExpression ProcessGroupBy(
Expression.Quote(elementSelector),
Expression.Quote(Visit(resultSelector)));
- var navigationTree = new NavigationTreeExpression(Expression.Default(result.Type.TryGetSequenceType()));
+ var navigationTree = new NavigationTreeExpression(Expression.Default(result.Type.GetSequenceType()));
var parameterName = GetParameterName("e");
return new NavigationExpansionExpression(result, navigationTree, navigationTree, parameterName);
@@ -928,7 +929,8 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi
var arguments = new List { filterExpression.Body };
arguments.AddRange(methodCallExpression.Arguments.Skip(1));
filterExpression = Expression.Lambda(
- methodCallExpression.Update(methodCallExpression.Object, arguments),
+ // TODO-Nullable bug
+ methodCallExpression.Update(methodCallExpression.Object!, arguments),
filterExpression.Parameters);
return (result, filterExpression);
@@ -953,7 +955,8 @@ static Expression FormatFilter(Expression expression)
arguments.Add(source);
arguments.AddRange(methodCallExpression.Arguments.Skip(1));
- return methodCallExpression.Update(methodCallExpression.Object, arguments);
+ // TODO-Nullable bug
+ return methodCallExpression.Update(methodCallExpression.Object!, arguments);
}
return expression;
@@ -977,8 +980,8 @@ private NavigationExpansionExpression ProcessJoin(
var transparentIdentifierType = TransparentIdentifierFactory.Create(
outerSource.SourceElementType, innerSource.SourceElementType);
- var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var newResultSelector = Expression.Lambda(
Expression.New(
@@ -1026,8 +1029,8 @@ private NavigationExpansionExpression ProcessLeftJoin(
var transparentIdentifierType = TransparentIdentifierFactory.Create(
outerSource.SourceElementType, innerSource.SourceElementType);
- var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var newResultSelector = Expression.Lambda(
Expression.New(
@@ -1140,8 +1143,7 @@ private NavigationExpansionExpression ProcessSelectMany(
collectionSource = (NavigationExpansionExpression)_pendingSelectorExpandingExpressionVisitor.Visit(collectionSource);
var innerTree = new NavigationTreeExpression(SnapshotExpression(collectionSource.PendingSelector));
collectionSelector = GenerateLambda(collectionSource, source.CurrentParameter);
- // Known to be sequence type
- var collectionElementType = collectionSelector.ReturnType.TryGetSequenceType()!;
+ var collectionElementType = collectionSelector.ReturnType.GetSequenceType();
// Collection selector body is IQueryable, we need to adjust the type to IEnumerable, to match the SelectMany signature
// therefore the delegate type is specified explicitly
@@ -1156,8 +1158,8 @@ private NavigationExpansionExpression ProcessSelectMany(
var transparentIdentifierType = TransparentIdentifierFactory.Create(
source.SourceElementType, collectionElementType);
- var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var transparentIdentifierOuterMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var transparentIdentifierInnerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
var collectionElementParameter = Expression.Parameter(collectionElementType, "c");
var newResultSelector = Expression.Lambda(
@@ -1210,9 +1212,8 @@ private NavigationExpansionExpression ProcessSetOperation(
var outerQueryable = Reduce(outerSource);
var innerQueryable = Reduce(innerSource);
- // Known to be sequence type
- var outerType = outerQueryable.Type.TryGetSequenceType()!;
- var innerType = innerQueryable.Type.TryGetSequenceType()!;
+ var outerType = outerQueryable.Type.GetSequenceType();
+ var innerType = innerQueryable.Type.GetSequenceType();
var result = Expression.Call(
genericMethod.MakeGenericMethod(outerType.IsAssignableFrom(innerType) ? outerType : innerType),
@@ -1411,7 +1412,7 @@ private Expression ApplyQueryFilter(IEntityType entityType, NavigationExpansionE
// We need to do entity equality, but that requires a full method call on a query root to properly flow the
// entity information through. Construct a MethodCall wrapper for the predicate with the proper query root.
var filterWrapper = Expression.Call(
- QueryableMethods.Where.MakeGenericMethod(rootEntityType.ClrType),
+ QueryableMethods.Where.MakeGenericMethod(rootEntityType.ClrType!),
new QueryRootExpression(rootEntityType),
filterPredicate);
filterPredicate = filterWrapper.Arguments[1].UnwrapLambdaFromQuote();
@@ -1700,7 +1701,7 @@ private Expression UnwrapCollectionMaterialization(Expression expression)
&& ownedNavigationReference.Navigation.IsCollection
? CreateNavigationExpansionExpression(
Expression.Call(
- QueryableMethods.AsQueryable.MakeGenericMethod(ownedNavigationReference.Type.TryGetSequenceType()),
+ QueryableMethods.AsQueryable.MakeGenericMethod(ownedNavigationReference.Type.GetSequenceType()),
ownedNavigationReference),
ownedNavigationReference)
: expression;
@@ -1792,7 +1793,8 @@ private IncludeTreeNode PopulateIncludeTree(IncludeTreeNode includeTreeNode, Exp
case ParameterExpression _:
return includeTreeNode;
- case MemberExpression memberExpression:
+ case MemberExpression memberExpression
+ when memberExpression.Expression != null:
var innerExpression = memberExpression.Expression.UnwrapTypeConversion(out var convertedType);
var innerIncludeTreeNode = PopulateIncludeTree(includeTreeNode, innerExpression);
var entityType = innerIncludeTreeNode.EntityType;
@@ -1871,7 +1873,7 @@ private Expression SnapshotExpression(Expression selector)
}
}
- private static EntityReference? UnwrapEntityReference(Expression expression)
+ private static EntityReference? UnwrapEntityReference(Expression? expression)
{
switch (expression)
{
@@ -1895,12 +1897,12 @@ private Expression SnapshotExpression(Expression selector)
private sealed class Parameters : IParameterValues
{
- private readonly IDictionary _parameterValues = new Dictionary();
+ private readonly IDictionary _parameterValues = new Dictionary();
- public IReadOnlyDictionary ParameterValues
- => (IReadOnlyDictionary)_parameterValues;
+ public IReadOnlyDictionary ParameterValues
+ => (IReadOnlyDictionary)_parameterValues;
- public void AddParameter(string name, object value)
+ public void AddParameter(string name, object? value)
{
_parameterValues.Add(name, value);
}
diff --git a/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs b/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
index afdc6662bbc..0d32a09a6c0 100644
--- a/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/NullCheckRemovingExpressionVisitor.cs
@@ -140,7 +140,8 @@ protected override Expression VisitMember(MemberExpression memberExpression)
Check.NotNull(memberExpression, nameof(memberExpression));
var innerExpression = Visit(memberExpression.Expression);
- if (_nullSafeAccesses.Contains(innerExpression))
+ if (innerExpression != null
+ && _nullSafeAccesses.Contains(innerExpression))
{
_nullSafeAccesses.Add(memberExpression);
}
diff --git a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
index 76f2801bd9f..80650ae92a6 100644
--- a/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/ParameterExtractingExpressionVisitor.cs
@@ -270,7 +270,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
return base.VisitExtension(extensionExpression);
}
- private static Expression GenerateConstantExpression(object value, Type returnType)
+ private static Expression GenerateConstantExpression(object? value, Type returnType)
{
var constantExpression = Expression.Constant(value, value?.GetType() ?? returnType);
@@ -355,7 +355,8 @@ public ContextParameterReplacingExpressionVisitor(Type contextType)
public ParameterExpression ContextParameterExpression { get; }
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
=> expression?.Type != typeof(object)
&& expression?.Type.IsAssignableFrom(_contextType) == true
? ContextParameterExpression
@@ -374,7 +375,6 @@ private static Expression RemoveConvert(Expression expression)
return expression;
}
- [return: CA.NotNullIfNotNull("expression")]
private object? GetValue(Expression? expression, out string? parameterName)
{
parameterName = null;
@@ -498,7 +498,8 @@ public IDictionary Find(Expression expression)
return _evaluatableExpressions;
}
- public override Expression Visit(Expression expression)
+ [return: CA.NotNullIfNotNull("expression")]
+ public override Expression? Visit(Expression? expression)
{
if (expression == null)
{
diff --git a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
index 5c9b8dcb595..5536ea6ed51 100644
--- a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs
@@ -21,16 +21,16 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
public class QueryOptimizingExpressionVisitor : ExpressionVisitor
{
private static readonly MethodInfo _stringCompareWithComparisonMethod =
- typeof(string).GetRuntimeMethod(nameof(string.Compare), new[] { typeof(string), typeof(string), typeof(StringComparison) });
+ typeof(string).GetRequiredRuntimeMethod(nameof(string.Compare), new[] { typeof(string), typeof(string), typeof(StringComparison) });
private static readonly MethodInfo _stringCompareWithoutComparisonMethod =
- typeof(string).GetRuntimeMethod(nameof(string.Compare), new[] { typeof(string), typeof(string) });
+ typeof(string).GetRequiredRuntimeMethod(nameof(string.Compare), new[] { typeof(string), typeof(string) });
private static readonly MethodInfo _startsWithMethodInfo =
- typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
+ typeof(string).GetRequiredRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) });
private static readonly MethodInfo _endsWithMethodInfo =
- typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
+ typeof(string).GetRequiredRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) });
private static readonly Expression _constantNullString = Expression.Constant(null, typeof(string));
@@ -57,17 +57,18 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
{
Check.NotNull(methodCallExpression, nameof(methodCallExpression));
- if (_startsWithMethodInfo.Equals(methodCallExpression.Method)
- || _endsWithMethodInfo.Equals(methodCallExpression.Method))
+ if (Equals(_startsWithMethodInfo, methodCallExpression.Method)
+ || Equals(_endsWithMethodInfo, methodCallExpression.Method))
{
if (methodCallExpression.Arguments[0] is ConstantExpression constantArgument
- && (string)constantArgument.Value == string.Empty)
+ && constantArgument.Value is string stringValue
+ && stringValue == string.Empty)
{
// every string starts/ends with empty string.
return Expression.Constant(true);
}
- var newObject = Visit(methodCallExpression.Object);
+ var newObject = Visit(methodCallExpression.Object)!;
var newArgument = Visit(methodCallExpression.Arguments[0]);
var result = Expression.AndAlso(
@@ -136,9 +137,12 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
&& visited.Method.DeclaringType?.Namespace == "Microsoft.VisualBasic.CompilerServices"
&& visited.Object == null
&& visited.Arguments.Count == 3
- && visited.Arguments[2] is ConstantExpression textCompareConstantExpression)
+ && visited.Arguments[2] is ConstantExpression textCompareConstantExpression
+ && _stringCompareWithComparisonMethod != null
+ && _stringCompareWithoutComparisonMethod != null)
{
- return (bool)textCompareConstantExpression.Value
+ return textCompareConstantExpression.Value is bool boolValue
+ && boolValue
? Expression.Call(
_stringCompareWithComparisonMethod,
visited.Arguments[0],
@@ -165,17 +169,18 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression)
if (unaryExpression.NodeType == ExpressionType.Not
&& unaryExpression.Operand is MethodCallExpression innerMethodCall
- && (_startsWithMethodInfo.Equals(innerMethodCall.Method)
- || _endsWithMethodInfo.Equals(innerMethodCall.Method)))
+ && (Equals(_startsWithMethodInfo, innerMethodCall.Method)
+ || Equals(_endsWithMethodInfo, innerMethodCall.Method)))
{
if (innerMethodCall.Arguments[0] is ConstantExpression constantArgument
- && (string)constantArgument.Value == string.Empty)
+ && constantArgument.Value is string stringValue
+ && stringValue == string.Empty)
{
// every string starts/ends with empty string.
return Expression.Constant(false);
}
- var newObject = Visit(innerMethodCall.Object);
+ var newObject = Visit(innerMethodCall.Object)!;
var newArgument = Visit(innerMethodCall.Arguments[0]);
var result = Expression.AndAlso(
@@ -227,7 +232,7 @@ private bool TryExtractEqualityOperands(
{
negated = false;
if (methodCallExpression.Arguments.Count == 1
- && methodCallExpression.Object.Type == methodCallExpression.Arguments[0].Type)
+ && methodCallExpression.Object?.Type == methodCallExpression.Arguments[0].Type)
{
(left, right) = (methodCallExpression.Object, methodCallExpression.Arguments[0]);
diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
index 42e458f962a..971c4b44f06 100644
--- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs
@@ -69,10 +69,11 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
visitedExpression = TryConvertEnumerableToQueryable(methodCallExpression);
}
- if (methodCallExpression.Method.DeclaringType.IsGenericType
- && (methodCallExpression.Method.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection<>)
- || methodCallExpression.Method.DeclaringType.GetGenericTypeDefinition() == typeof(List<>))
- && methodCallExpression.Method.Name == nameof(List.Contains))
+ if (method.DeclaringType != null
+ && method.DeclaringType.IsGenericType
+ && (method.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection<>)
+ || method.DeclaringType.GetGenericTypeDefinition() == typeof(List<>))
+ && method.Name == nameof(List.Contains))
{
visitedExpression = TryConvertListContainsToQueryableContains(methodCallExpression);
}
@@ -111,7 +112,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return Expression.Call(newIncludeMethod, source, lambda);
}
- return methodCallExpression.Update(null, new[] { source, lambda });
+ // TODO-Nullable bug
+ return methodCallExpression.Update(null!, new[] { source, lambda });
}
}
@@ -207,7 +209,7 @@ private void VerifyReturnType(Expression expression, ParameterExpression lambdaP
if (genericMethodDefinition == EntityFrameworkQueryableExtensions.TagWithMethodInfo)
{
var visitedExpression = Visit(methodCallExpression.Arguments[0]);
- _queryCompilationContext.AddTag((string)((ConstantExpression)methodCallExpression.Arguments[1]).Value);
+ _queryCompilationContext.AddTag(methodCallExpression.Arguments[1].GetConstantValue());
return visitedExpression;
}
@@ -318,7 +320,7 @@ private Expression TryConvertEnumerableToQueryable(MethodCallExpression methodCa
if (CanConvertEnumerableToQueryable(enumerableParameterType, queryableParameterType))
{
var innerArgument = arguments[i];
- var genericType = innerArgument.Type.TryGetSequenceType();
+ var genericType = innerArgument.Type.GetSequenceType();
// If innerArgument has ToList applied to it then unwrap it.
// Also preserve generic argument of ToList is applied to different type
@@ -363,7 +365,8 @@ private Expression TryConvertEnumerableToQueryable(MethodCallExpression methodCa
}
}
- return methodCallExpression.Update(Visit(methodCallExpression.Object), arguments);
+ // TODO-Nullable bug
+ return methodCallExpression.Update(Visit(methodCallExpression.Object)!, arguments);
}
private Expression TryConvertListContainsToQueryableContains(MethodCallExpression methodCallExpression)
@@ -374,17 +377,17 @@ private Expression TryConvertListContainsToQueryableContains(MethodCallExpressio
return base.VisitMethodCall(methodCallExpression);
}
- var sourceType = methodCallExpression.Method.DeclaringType.GetGenericArguments()[0];
+ var sourceType = methodCallExpression.Method.DeclaringType!.GetGenericArguments()[0];
return Expression.Call(
QueryableMethods.Contains.MakeGenericMethod(sourceType),
Expression.Call(
QueryableMethods.AsQueryable.MakeGenericMethod(sourceType),
- methodCallExpression.Object),
+ methodCallExpression.Object!),
methodCallExpression.Arguments[0]);
}
- private static bool ClientSource(Expression expression)
+ private static bool ClientSource(Expression? expression)
=> expression is ConstantExpression
|| expression is MemberInitExpression
|| expression is NewExpression
@@ -486,8 +489,8 @@ private Expression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCall
// left join
return Expression.Call(
QueryableExtensions.LeftJoinMethodInfo.MakeGenericMethod(
- outer.Type.TryGetSequenceType(),
- inner.Type.TryGetSequenceType(),
+ outer.Type.GetSequenceType(),
+ inner.Type.GetSequenceType(),
outerKeySelector.ReturnType,
resultSelector.ReturnType),
outer,
@@ -500,8 +503,8 @@ private Expression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCall
// inner join
return Expression.Call(
QueryableMethods.Join.MakeGenericMethod(
- outer.Type.TryGetSequenceType(),
- inner.Type.TryGetSequenceType(),
+ outer.Type.GetSequenceType(),
+ inner.Type.GetSequenceType(),
outerKeySelector.ReturnType,
resultSelector.ReturnType),
outer,
@@ -520,7 +523,7 @@ private Expression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCall
// innerKeySelector.Body);
// inner = Expression.Call(
- // QueryableMethods.Where.MakeGenericMethod(inner.Type.TryGetSequenceType()),
+ // QueryableMethods.Where.MakeGenericMethod(inner.Type.GetSequenceType()),
// inner,
// Expression.Quote(Expression.Lambda(correlationPredicate, innerParameter)));
@@ -600,8 +603,8 @@ private Expression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCall
// left join
return Expression.Call(
QueryableExtensions.LeftJoinMethodInfo.MakeGenericMethod(
- outer.Type.TryGetSequenceType(),
- inner.Type.TryGetSequenceType(),
+ outer.Type.GetSequenceType(),
+ inner.Type.GetSequenceType(),
outerKeySelector.ReturnType,
resultSelector.ReturnType),
outer,
@@ -614,8 +617,8 @@ private Expression TryFlattenGroupJoinSelectMany(MethodCallExpression methodCall
// inner join
return Expression.Call(
QueryableMethods.Join.MakeGenericMethod(
- outer.Type.TryGetSequenceType(),
- inner.Type.TryGetSequenceType(),
+ outer.Type.GetSequenceType(),
+ inner.Type.GetSequenceType(),
outerKeySelector.ReturnType,
resultSelector.ReturnType),
outer,
diff --git a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
index 9065b1ec957..70e15da3440 100644
--- a/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
+++ b/src/EFCore/Query/Internal/SubqueryMemberPushdownExpressionVisitor.cs
@@ -169,7 +169,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
var updatedMemberExpression = memberExpression.Update(Visit(memberExpression.Expression));
return Expression.Call(
- QueryableMethods.AsQueryable.MakeGenericMethod(updatedMemberExpression.Type.TryGetSequenceType()),
+ QueryableMethods.AsQueryable.MakeGenericMethod(updatedMemberExpression.Type.GetSequenceType()),
updatedMemberExpression);
}
@@ -182,7 +182,7 @@ private Expression PushdownMember(
Type returnType)
{
var source = methodCallExpression.Arguments[0];
- var queryableType = source.Type.TryGetSequenceType();
+ var queryableType = source.Type.GetSequenceType();
var genericMethod = methodCallExpression.Method.GetGenericMethodDefinition();
if (methodCallExpression.Arguments.Count == 2)
{
@@ -206,7 +206,7 @@ private Expression PushdownMember(
source = Expression.Call(
QueryableMethods.Select.MakeGenericMethod(
- sourceMethodCallExpression.Arguments[0].Type.TryGetSequenceType(), memberAccessExpression.Type),
+ sourceMethodCallExpression.Arguments[0].Type.GetSequenceType(), memberAccessExpression.Type),
sourceMethodCallExpression.Arguments[0],
Expression.Quote(Expression.Lambda(memberAccessExpression, selector.Parameters[0])));
@@ -224,7 +224,7 @@ private Expression PushdownMember(
Expression.Quote(Expression.Lambda(memberAccessExpression, parameter)));
}
- source = Expression.Call(genericMethod.MakeGenericMethod(source.Type.TryGetSequenceType()), source);
+ source = Expression.Call(genericMethod.MakeGenericMethod(source.Type.GetSequenceType()), source);
return source.Type != returnType
? Expression.Convert(source, returnType)
diff --git a/src/EFCore/Query/ProjectionBindingExpression.cs b/src/EFCore/Query/ProjectionBindingExpression.cs
index 94a5fab35d9..617736a46ce 100644
--- a/src/EFCore/Query/ProjectionBindingExpression.cs
+++ b/src/EFCore/Query/ProjectionBindingExpression.cs
@@ -128,7 +128,7 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
}
else if (Index != null)
{
- expressionPrinter.Append(Index.ToString());
+ expressionPrinter.Append(Index.ToString()!);
}
else if (IndexMap != null)
{
diff --git a/src/EFCore/Query/ProjectionMember.cs b/src/EFCore/Query/ProjectionMember.cs
index d2a130ac248..44c9a2e469f 100644
--- a/src/EFCore/Query/ProjectionMember.cs
+++ b/src/EFCore/Query/ProjectionMember.cs
@@ -80,7 +80,7 @@ public ProjectionMember Prepend([NotNull] MemberInfo member)
/// This method is generally used to get last memberInfo to generate an alias for projection.
///
///
- public MemberInfo Last
+ public MemberInfo? Last
=> _memberChain.LastOrDefault();
///
diff --git a/src/EFCore/Query/QueryCompilationContext.cs b/src/EFCore/Query/QueryCompilationContext.cs
index ba57ca4542a..913b4a2d2c2 100644
--- a/src/EFCore/Query/QueryCompilationContext.cs
+++ b/src/EFCore/Query/QueryCompilationContext.cs
@@ -49,6 +49,17 @@ public class QueryCompilationContext
///
public static readonly ParameterExpression QueryContextParameter = Expression.Parameter(typeof(QueryContext), "queryContext");
+ ///
+ ///
+ /// Expression representing a not translated expression in query tree during translation phase.
+ ///
+ ///
+ /// This property is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ public static readonly Expression NotTranslatedExpression = new NotTranslatedExpressionType();
+
private readonly IQueryTranslationPreprocessorFactory _queryTranslationPreprocessorFactory;
private readonly IQueryableMethodTranslatingExpressionVisitorFactory _queryableMethodTranslatingExpressionVisitorFactory;
private readonly IQueryTranslationPostprocessorFactory _queryTranslationPostprocessorFactory;
@@ -238,8 +249,12 @@ private Expression InsertRuntimeParameters(Expression query)
.Append(query));
private static readonly MethodInfo _queryContextAddParameterMethodInfo
- = typeof(QueryContext)
- .GetTypeInfo()
- .GetDeclaredMethod(nameof(QueryContext.AddParameter));
+ = typeof(QueryContext).GetRequiredDeclaredMethod(nameof(QueryContext.AddParameter));
+
+ private sealed class NotTranslatedExpressionType : Expression
+ {
+ public override Type Type => typeof(object);
+ public override ExpressionType NodeType => ExpressionType.Extension;
+ }
}
}
diff --git a/src/EFCore/Query/QueryContext.cs b/src/EFCore/Query/QueryContext.cs
index 9568ebfe42b..647bf118578 100644
--- a/src/EFCore/Query/QueryContext.cs
+++ b/src/EFCore/Query/QueryContext.cs
@@ -29,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.Query
///
public abstract class QueryContext : IParameterValues
{
- private readonly IDictionary _parameterValues = new Dictionary();
+ private readonly IDictionary _parameterValues = new Dictionary();
private IStateManager? _stateManager;
///
@@ -114,15 +114,15 @@ public virtual IDiagnosticsLogger QueryLogger
///
/// The parameter values to use while executing the query.
///
- public virtual IReadOnlyDictionary ParameterValues
- => (IReadOnlyDictionary)_parameterValues;
+ public virtual IReadOnlyDictionary ParameterValues
+ => (IReadOnlyDictionary)_parameterValues;
///
/// Adds a parameter to for this query.
///
/// The name.
/// The value.
- public virtual void AddParameter(string name, object value)
+ public virtual void AddParameter(string name, object? value)
{
Check.NotEmpty(name, nameof(name));
diff --git a/src/EFCore/Query/QueryRootExpression.cs b/src/EFCore/Query/QueryRootExpression.cs
index 00fbf6201fb..f8efa45dcc4 100644
--- a/src/EFCore/Query/QueryRootExpression.cs
+++ b/src/EFCore/Query/QueryRootExpression.cs
@@ -36,7 +36,7 @@ public QueryRootExpression([NotNull] IAsyncQueryProvider asyncQueryProvider, [No
QueryProvider = asyncQueryProvider;
EntityType = entityType;
- Type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType);
+ Type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType!);
}
///
@@ -49,7 +49,7 @@ public QueryRootExpression([NotNull] IEntityType entityType)
EntityType = entityType;
QueryProvider = null;
- Type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType);
+ Type = typeof(IQueryable<>).MakeGenericType(entityType.ClrType!);
}
///
diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
index de17d177875..f51fa869eb5 100644
--- a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
@@ -85,7 +85,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
protected virtual QueryCompilationContext QueryCompilationContext { get; }
///
- protected override Expression? VisitExtension(Expression extensionExpression)
+ protected override Expression VisitExtension(Expression extensionExpression)
{
Check.NotNull(extensionExpression, nameof(extensionExpression));
@@ -98,7 +98,7 @@ protected virtual void AddTranslationErrorDetails([NotNull] string details)
}
///
- protected override Expression? VisitMethodCall(MethodCallExpression methodCallExpression)
+ protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
Check.NotNull(methodCallExpression, nameof(methodCallExpression));
@@ -163,9 +163,9 @@ when QueryableMethods.IsAverageWithSelector(method):
var source2 = Visit(methodCallExpression.Arguments[1]);
if (source2 is ShapedQueryExpression innerShapedQueryExpression)
{
- return TranslateConcat(
+ return CheckTranslated(TranslateConcat(
shapedQueryExpression,
- innerShapedQueryExpression);
+ innerShapedQueryExpression));
}
break;
@@ -495,7 +495,7 @@ LambdaExpression GetLambdaExpressionFromArgument(int argumentIndex)
}
return _subquery
- ? (Expression?)null
+ ? QueryCompilationContext.NotTranslatedExpression
: throw new InvalidOperationException(CoreStrings.TranslationFailed(methodCallExpression.Print()));
}
@@ -571,8 +571,8 @@ private Expression CombineShapers(
Expression innerShaper,
Type transparentIdentifierType)
{
- var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
- var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var outerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
+ var innerMemberInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
outerShaper = new MemberAccessShiftingExpressionVisitor(queryExpression, outerMemberInfo).Visit(outerShaper);
innerShaper = new MemberAccessShiftingExpressionVisitor(queryExpression, innerMemberInfo).Visit(innerShaper);
@@ -612,7 +612,7 @@ private static Expression AccessOuterTransparentField(
Type transparentIdentifierType,
Expression targetExpression)
{
- var fieldInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Outer");
+ var fieldInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Outer");
return Expression.Field(targetExpression, fieldInfo);
}
@@ -622,7 +622,7 @@ private static Expression AccessInnerTransparentField(
Type transparentIdentifierType,
Expression targetExpression)
{
- var fieldInfo = transparentIdentifierType.GetTypeInfo().GetDeclaredField("Inner");
+ var fieldInfo = transparentIdentifierType.GetTypeInfo().GetRequiredDeclaredField("Inner");
return Expression.Field(targetExpression, fieldInfo);
}
@@ -658,14 +658,14 @@ private static Expression AccessInnerTransparentField(
/// The clr type of the entity type to look for.
/// A shaped query expression for the given clr type.
[Obsolete("Use overload which takes IEntityType.")]
- protected abstract ShapedQueryExpression? CreateShapedQueryExpression([NotNull] Type elementType);
+ protected abstract ShapedQueryExpression CreateShapedQueryExpression([NotNull] Type elementType);
///
/// Creates a for the given entity type.
///
/// The the entity type.
/// A shaped query expression for the given entity type.
- protected abstract ShapedQueryExpression? CreateShapedQueryExpression([NotNull] IEntityType entityType);
+ protected abstract ShapedQueryExpression CreateShapedQueryExpression([NotNull] IEntityType entityType);
///
/// Translates method over the given source.
diff --git a/src/EFCore/Query/ReplacingExpressionVisitor.cs b/src/EFCore/Query/ReplacingExpressionVisitor.cs
index d8c2d281ff1..d3433df558d 100644
--- a/src/EFCore/Query/ReplacingExpressionVisitor.cs
+++ b/src/EFCore/Query/ReplacingExpressionVisitor.cs
@@ -140,7 +140,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
return memberAssignment.Expression;
}
- return methodCallExpression.Update(null, new[] { newEntityExpression, methodCallExpression.Arguments[1] });
+ // TODO-Nullable bug
+ return methodCallExpression.Update(null!, new[] { newEntityExpression, methodCallExpression.Arguments[1] });
}
return base.VisitMethodCall(methodCallExpression);
diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
index e277e16c3f7..5ccd52910d0 100644
--- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
@@ -41,9 +41,9 @@ namespace Microsoft.EntityFrameworkCore.Query
public abstract class ShapedQueryCompilingExpressionVisitor : ExpressionVisitor
{
private static readonly PropertyInfo _cancellationTokenMemberInfo
- = typeof(QueryContext).GetProperty(nameof(QueryContext.CancellationToken));
+ = typeof(QueryContext).GetRequiredProperty(nameof(QueryContext.CancellationToken));
- private readonly Expression? _cancellationTokenParameter;
+ private readonly Expression _cancellationTokenParameter;
private readonly EntityMaterializerInjectingExpressionVisitor _entityMaterializerInjectingExpressionVisitor;
private readonly ConstantVerifyingExpressionVisitor _constantVerifyingExpressionVisitor;
@@ -75,6 +75,10 @@ protected ShapedQueryCompilingExpressionVisitor(
QueryCompilationContext.QueryContextParameter,
_cancellationTokenMemberInfo);
}
+ else
+ {
+ _cancellationTokenParameter = null!;
+ }
}
///
@@ -103,22 +107,22 @@ protected override Expression VisitExtension(Expression extensionExpression)
case ResultCardinality.Single:
return QueryCompilationContext.IsAsync
? Expression.Call(
- _singleAsyncMethodInfo.MakeGenericMethod(serverEnumerable.Type.TryGetSequenceType()),
+ _singleAsyncMethodInfo.MakeGenericMethod(serverEnumerable.Type.GetSequenceType()),
serverEnumerable,
_cancellationTokenParameter)
: Expression.Call(
- EnumerableMethods.SingleWithoutPredicate.MakeGenericMethod(serverEnumerable.Type.TryGetSequenceType()),
+ EnumerableMethods.SingleWithoutPredicate.MakeGenericMethod(serverEnumerable.Type.GetSequenceType()),
serverEnumerable);
case ResultCardinality.SingleOrDefault:
return QueryCompilationContext.IsAsync
? Expression.Call(
- _singleOrDefaultAsyncMethodInfo.MakeGenericMethod(serverEnumerable.Type.TryGetSequenceType()),
+ _singleOrDefaultAsyncMethodInfo.MakeGenericMethod(serverEnumerable.Type.GetSequenceType()),
serverEnumerable,
_cancellationTokenParameter)
: Expression.Call(
EnumerableMethods.SingleOrDefaultWithoutPredicate.MakeGenericMethod(
- serverEnumerable.Type.TryGetSequenceType()),
+ serverEnumerable.Type.GetSequenceType()),
serverEnumerable);
}
}
@@ -301,20 +305,20 @@ private static readonly ConstructorInfo _valueBufferConstructor
= typeof(ValueBuffer).GetTypeInfo().DeclaredConstructors.Single(ci => ci.GetParameters().Length == 1);
private static readonly PropertyInfo _dbContextMemberInfo
- = typeof(QueryContext).GetProperty(nameof(QueryContext.Context));
+ = typeof(QueryContext).GetRequiredProperty(nameof(QueryContext.Context));
private static readonly PropertyInfo _entityMemberInfo
- = typeof(InternalEntityEntry).GetProperty(nameof(InternalEntityEntry.Entity));
+ = typeof(InternalEntityEntry).GetRequiredProperty(nameof(InternalEntityEntry.Entity));
private static readonly PropertyInfo _entityTypeMemberInfo
- = typeof(InternalEntityEntry).GetProperty(nameof(InternalEntityEntry.EntityType));
+ = typeof(InternalEntityEntry).GetRequiredProperty(nameof(InternalEntityEntry.EntityType));
private static readonly MethodInfo _tryGetEntryMethodInfo
= typeof(QueryContext).GetTypeInfo().GetDeclaredMethods(nameof(QueryContext.TryGetEntry))
.Single(mi => mi.GetParameters().Length == 4);
private static readonly MethodInfo _startTrackingMethodInfo
- = typeof(QueryContext).GetMethod(
+ = typeof(QueryContext).GetRequiredMethod(
nameof(QueryContext.StartTracking), new[] { typeof(IEntityType), typeof(object), typeof(ValueBuffer) });
private readonly IEntityMaterializerSource _entityMaterializerSource;
@@ -395,12 +399,12 @@ private Expression ProcessEntityShaper(EntityShaperExpression entityShaperExpres
"entityType" + _currentEntityIndex);
variables.Add(concreteEntityTypeVariable);
- var instanceVariable = Expression.Variable(entityType.ClrType, "instance" + _currentEntityIndex);
+ var instanceVariable = Expression.Variable(entityType.ClrType!, "instance" + _currentEntityIndex);
variables.Add(instanceVariable);
expressions.Add(
Expression.Assign(
instanceVariable,
- Expression.Constant(null, entityType.ClrType)));
+ Expression.Constant(null, entityType.ClrType!)));
if (_queryStateMananger
&& primaryKey != null)
@@ -442,7 +446,7 @@ private Expression ProcessEntityShaper(EntityShaperExpression entityShaperExpres
Expression.Assign(
instanceVariable, Expression.Convert(
Expression.MakeMemberAccess(entryVariable, _entityMemberInfo),
- entityType.ClrType))),
+ entityType.ClrType!))),
MaterializeEntity(
entityShaperExpression, materializationContextVariable, concreteEntityTypeVariable, instanceVariable,
entryVariable))));
@@ -536,7 +540,7 @@ private Expression MaterializeEntity(
expressions.Add(
Expression.Assign(
- entryVariable,
+ entryVariable!,
Expression.Condition(
Expression.Equal(concreteEntityTypeVariable, Expression.Default(typeof(IEntityType))),
Expression.Default(typeof(InternalEntityEntry)),
diff --git a/src/Shared/ExpressionExtensions.cs b/src/Shared/ExpressionExtensions.cs
index 551ba80ef06..9587cec81ba 100644
--- a/src/Shared/ExpressionExtensions.cs
+++ b/src/Shared/ExpressionExtensions.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using JetBrains.Annotations;
+using CA = System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -21,7 +22,8 @@ public static LambdaExpression UnwrapLambdaFromQuote(this Expression expression)
? unary.Operand
: expression);
- public static Expression UnwrapTypeConversion(this Expression expression, out Type? convertedType)
+ [return: CA.NotNullIfNotNull("expression")]
+ public static Expression? UnwrapTypeConversion(this Expression? expression, out Type? convertedType)
{
convertedType = null;
while (expression is UnaryExpression unaryExpression
@@ -51,5 +53,10 @@ private static Expression RemoveConvert(Expression expression)
return expression;
}
+
+ public static T GetConstantValue(this Expression expression)
+ => expression is ConstantExpression constantExpression
+ ? (T)constantExpression.Value!
+ : throw new InvalidOperationException();
}
}
diff --git a/src/Shared/MemberInfoExtensions.cs b/src/Shared/MemberInfoExtensions.cs
index eadbe488495..046e6fe66b7 100644
--- a/src/Shared/MemberInfoExtensions.cs
+++ b/src/Shared/MemberInfoExtensions.cs
@@ -5,7 +5,8 @@
namespace System.Reflection
{
- internal static class MemberInfoExtensions
+ internal static class EntityFrameworkMemberInfoExtensions
+
{
public static Type GetMemberType(this MemberInfo memberInfo)
=> (memberInfo as PropertyInfo)?.PropertyType ?? ((FieldInfo)memberInfo)?.FieldType;
diff --git a/src/Shared/SharedTypeExtensions.cs b/src/Shared/SharedTypeExtensions.cs
index cc3b96a7ea0..a4b0253f9bc 100644
--- a/src/Shared/SharedTypeExtensions.cs
+++ b/src/Shared/SharedTypeExtensions.cs
@@ -10,6 +10,8 @@
using System.Text;
using JetBrains.Annotations;
+#nullable enable
+
// ReSharper disable once CheckNamespace
namespace System
{
@@ -131,7 +133,7 @@ public static bool IsTupleType(this Type type)
return false;
}
- public static PropertyInfo GetAnyProperty(this Type type, string name)
+ public static PropertyInfo? GetAnyProperty(this Type type, string name)
{
var props = type.GetRuntimeProperties().Where(p => p.Name == name).ToList();
if (props.Count > 1)
@@ -142,6 +144,90 @@ public static PropertyInfo GetAnyProperty(this Type type, string name)
return props.SingleOrDefault();
}
+ public static MethodInfo GetRequiredMethod(this Type type, string name, params Type[] parameters)
+ {
+ var method = type.GetTypeInfo().GetMethod(name, parameters);
+
+ if (method == null
+ && parameters.Length == 0)
+ {
+ method = type.GetMethod(name);
+ }
+
+ if (method == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return method;
+ }
+
+ public static PropertyInfo GetRequiredProperty(this Type type, string name)
+ {
+ var property = type.GetTypeInfo().GetProperty(name);
+ if (property == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return property;
+ }
+
+ public static FieldInfo GetRequiredDeclaredField(this Type type, string name)
+ {
+ var field = type.GetTypeInfo().GetDeclaredField(name);
+ if (field == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return field;
+ }
+
+ public static MethodInfo GetRequiredDeclaredMethod(this Type type, string name)
+ {
+ var method = type.GetTypeInfo().GetDeclaredMethod(name);
+ if (method == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return method;
+ }
+
+ public static PropertyInfo GetRequiredDeclaredProperty(this Type type, string name)
+ {
+ var property = type.GetTypeInfo().GetDeclaredProperty(name);
+ if (property == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return property;
+ }
+
+ public static MethodInfo GetRequiredRuntimeMethod(this Type type, string name, params Type[] parameters)
+ {
+ var method = type.GetTypeInfo().GetRuntimeMethod(name, parameters);
+ if (method == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return method;
+ }
+
+ public static PropertyInfo GetRequiredRuntimeProperty(this Type type, string name)
+ {
+ var property = type.GetTypeInfo().GetRuntimeProperty(name);
+ if (property == null)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return property;
+ }
+
public static bool IsInstantiable(this Type type)
=> !type.IsAbstract
&& !type.IsInterface
diff --git a/test/Directory.Build.props b/test/Directory.Build.props
index c054a3fb4bd..86571cd8ba2 100644
--- a/test/Directory.Build.props
+++ b/test/Directory.Build.props
@@ -1,11 +1,6 @@
-
- $(DefaultNetCoreTargetFramework)
- $(StandardTestTfms);netcoreapp3.1
-
-
$(NoWarn);CA1707;1591;xUnit1000;xUnit1003;xUnit1004;xUnit1010;xUnit1013;xUnit1026
diff --git a/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj b/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
index 20045b2a73e..d68e8bdd40f 100644
--- a/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
+++ b/test/EFCore.Analyzers.Tests/EFCore.Analyzers.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Analyzers.Tests
Microsoft.EntityFrameworkCore
true
diff --git a/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj b/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
index 66cab175486..4476f37dc52 100644
--- a/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
+++ b/test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj
@@ -1,8 +1,7 @@
- $(StandardTestTfms)
- $(DefaultNetCoreTargetFramework)
+ net5.0
Microsoft.EntityFrameworkCore.Cosmos.FunctionalTests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosDbConfiguredConditionAttribute.cs b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosDbConfiguredConditionAttribute.cs
index ca91b1850bf..ed75f2ebf2e 100644
--- a/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosDbConfiguredConditionAttribute.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/TestUtilities/CosmosDbConfiguredConditionAttribute.cs
@@ -2,16 +2,13 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestUtilities.Xunit;
-#if NET5_0
-using System.IO;
-#endif
-
namespace Microsoft.EntityFrameworkCore.TestUtilities
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
@@ -71,12 +68,8 @@ private static async Task TryConnectAsync()
private static bool IsNotConfigured(Exception exception)
=> exception switch
{
- HttpRequestException re => re.InnerException is SocketException
-#if NET5_0
- || (re.InnerException is IOException networkException
- && networkException.InnerException is SocketException)
-#endif
- ,
+ HttpRequestException re => re.InnerException is SocketException // Exception in Mac/Linux
+ || (re.InnerException is IOException ioException && ioException.InnerException is SocketException), // Exception in Windows
_ => exception.Message.Contains(
"The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used.",
StringComparison.Ordinal),
diff --git a/test/EFCore.Cosmos.Tests/EFCore.Cosmos.Tests.csproj b/test/EFCore.Cosmos.Tests/EFCore.Cosmos.Tests.csproj
index 8769167926a..092602ee0d0 100644
--- a/test/EFCore.Cosmos.Tests/EFCore.Cosmos.Tests.csproj
+++ b/test/EFCore.Cosmos.Tests/EFCore.Cosmos.Tests.csproj
@@ -1,8 +1,7 @@
- $(StandardTestTfms)
- $(DefaultNetCoreTargetFramework)
+ net5.0
Microsoft.EntityFrameworkCore.Cosmos.Tests
Microsoft.EntityFrameworkCore.Cosmos
diff --git a/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj b/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj
index 8c6c62cc11a..5be8fbf8d14 100644
--- a/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj
+++ b/test/EFCore.CrossStore.FunctionalTests/EFCore.CrossStore.FunctionalTests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.CrossStore.FunctionalTests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
index 78604fd4692..1f11db3b6ea 100644
--- a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
+++ b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
true
Microsoft.EntityFrameworkCore.Design.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.InMemory.FunctionalTests/EFCore.InMemory.FunctionalTests.csproj b/test/EFCore.InMemory.FunctionalTests/EFCore.InMemory.FunctionalTests.csproj
index e57c8fc8cb3..68ac9c2e3e2 100644
--- a/test/EFCore.InMemory.FunctionalTests/EFCore.InMemory.FunctionalTests.csproj
+++ b/test/EFCore.InMemory.FunctionalTests/EFCore.InMemory.FunctionalTests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.InMemory.FunctionalTests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.InMemory.Tests/EFCore.InMemory.Tests.csproj b/test/EFCore.InMemory.Tests/EFCore.InMemory.Tests.csproj
index a3507ee18e7..4281caef41e 100644
--- a/test/EFCore.InMemory.Tests/EFCore.InMemory.Tests.csproj
+++ b/test/EFCore.InMemory.Tests/EFCore.InMemory.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.InMemory.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj b/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
index 5565ed95691..9f4be8c8741 100644
--- a/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
+++ b/test/EFCore.OData.FunctionalTests/EFCore.OData.FunctionalTests.csproj
@@ -1,12 +1,11 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.OData.FunctionalTests
Microsoft.EntityFrameworkCore
- true
True
-
+
diff --git a/test/EFCore.Proxies.Tests/EFCore.Proxies.Tests.csproj b/test/EFCore.Proxies.Tests/EFCore.Proxies.Tests.csproj
index 8b26bc1b1fe..c494ea7371d 100644
--- a/test/EFCore.Proxies.Tests/EFCore.Proxies.Tests.csproj
+++ b/test/EFCore.Proxies.Tests/EFCore.Proxies.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Proxies.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj b/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
index 891cc0fa866..4d3d35d18ca 100644
--- a/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
+++ b/test/EFCore.Relational.Specification.Tests/EFCore.Relational.Specification.Tests.csproj
@@ -2,7 +2,7 @@
Shared test suite for Entity Framework Core relational database providers.
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Relational.Specification.Tests
Microsoft.EntityFrameworkCore
true
diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs
index 8485ea7484f..3bc2d306412 100644
--- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs
@@ -154,7 +154,7 @@ protected override Expression RewriteServerQueryExpression(Expression serverQuer
serverQueryExpression = base.RewriteServerQueryExpression(serverQueryExpression);
return Expression.Call(
- _asSplitIncludeMethodInfo.MakeGenericMethod(serverQueryExpression.Type.TryGetSequenceType()),
+ _asSplitIncludeMethodInfo.MakeGenericMethod(serverQueryExpression.Type.GetSequenceType()),
serverQueryExpression);
}
}
diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs
index 1bf45c0b5cf..de18c77121a 100644
--- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs
@@ -142,7 +142,7 @@ protected override Expression RewriteServerQueryExpression(Expression serverQuer
serverQueryExpression = base.RewriteServerQueryExpression(serverQueryExpression);
return Expression.Call(
- _asSplitIncludeMethodInfo.MakeGenericMethod(serverQueryExpression.Type.TryGetSequenceType()),
+ _asSplitIncludeMethodInfo.MakeGenericMethod(serverQueryExpression.Type.GetSequenceType()),
serverQueryExpression);
}
}
diff --git a/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj b/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
index d2ff362d6e3..a201c553974 100644
--- a/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
+++ b/test/EFCore.Relational.Tests/EFCore.Relational.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Relational.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
index 610e4f0533c..665c595cd29 100644
--- a/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
+++ b/test/EFCore.Specification.Tests/EFCore.Specification.Tests.csproj
@@ -2,7 +2,7 @@
Shared test suite for Entity Framework Core database providers.
- $(StandardTestTfms)
+ net5.0
9.0
Microsoft.EntityFrameworkCore.Specification.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs
index cc4f9643b94..f947893268a 100644
--- a/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs
+++ b/test/EFCore.Specification.Tests/LazyLoadProxyTestBase.cs
@@ -2104,7 +2104,6 @@ public virtual void Can_serialize_proxies_to_JSON()
Assert.IsType(blog);
}
-#if NET5_0
var options = new System.Text.Json.JsonSerializerOptions { ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve, WriteIndented = true };
serialized = System.Text.Json.JsonSerializer.Serialize(blogs, options);
@@ -2177,7 +2176,6 @@ public virtual void Can_serialize_proxies_to_JSON()
Assert.IsType(blog);
}
VerifyBlogs(newBlogs);
-#endif
}
[ConditionalFact]
diff --git a/test/EFCore.Specification.Tests/SerializationTestBase.cs b/test/EFCore.Specification.Tests/SerializationTestBase.cs
index d9e99608e3c..97c38729dfd 100644
--- a/test/EFCore.Specification.Tests/SerializationTestBase.cs
+++ b/test/EFCore.Specification.Tests/SerializationTestBase.cs
@@ -122,7 +122,6 @@ private static T RoundtripThroughBclJson(T collection, bool ignoreLoops, bool
{
Assert.False(ignoreLoops, "BCL doesn't support ignoring loops.");
-#if NET5_0
var options = new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.Preserve,
@@ -131,9 +130,6 @@ private static T RoundtripThroughBclJson(T collection, bool ignoreLoops, bool
};
return JsonSerializer.Deserialize(JsonSerializer.Serialize(collection, options), options);
-#else
- return collection;
-#endif
}
private static T RoundtripThroughNewtonsoftJson(T collection, bool ignoreLoops, bool writeIndented)
diff --git a/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs b/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs
index 4b4120b58a8..bd9a7ce0ed2 100644
--- a/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs
+++ b/test/EFCore.Specification.Tests/WithConstructorsTestBase.cs
@@ -743,7 +743,6 @@ public virtual void Query_with_loader_delegate_injected_into_property_via_constr
Assert.Same(blog, blog.LazyPcsPosts.Skip(1).First().LazyPcsBlog);
}
-#if NET5_0
[ConditionalFact]
public virtual async Task Add_immutable_record()
{
@@ -765,7 +764,6 @@ public virtual async Task Add_immutable_record()
Assert.Equal(title, context.Set().Single(e => e.BlogId == blogId).Title);
}
}
-#endif
protected class Blog
{
@@ -1581,7 +1579,6 @@ public async Task LoadBlogAsync(CancellationToken cancellationTok
public LazyAsyncBlog LazyAsyncBlog { get; set; }
}
-#if NET5_0
protected record BlogAsImmutableRecord
{
public BlogAsImmutableRecord(
@@ -1606,7 +1603,6 @@ private BlogAsImmutableRecord(
public string Title { get; init; }
public int? MonthlyRevenue { get; init; }
}
-#endif
public class OtherContext : DbContext
{
@@ -1679,9 +1675,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
modelBuilder.Entity();
modelBuilder.Entity();
-#if NET5_0
modelBuilder.Entity();
-#endif
// Manually configure service fields since there is no public API yet
diff --git a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
index f8333ed07d5..8cd8c7d42ea 100644
--- a/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
+++ b/test/EFCore.SqlServer.FunctionalTests/EFCore.SqlServer.FunctionalTests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.SqlServer.FunctionalTests
Microsoft.EntityFrameworkCore
True
diff --git a/test/EFCore.SqlServer.Tests/EFCore.SqlServer.Tests.csproj b/test/EFCore.SqlServer.Tests/EFCore.SqlServer.Tests.csproj
index 6fe3547b9aa..746ec1c4d38 100644
--- a/test/EFCore.SqlServer.Tests/EFCore.SqlServer.Tests.csproj
+++ b/test/EFCore.SqlServer.Tests/EFCore.SqlServer.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.SqlServer.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj b/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
index c58af715a5e..c9fe4d12d0c 100644
--- a/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
+++ b/test/EFCore.Sqlite.FunctionalTests/EFCore.Sqlite.FunctionalTests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Sqlite.FunctionalTests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Sqlite.Tests/EFCore.Sqlite.Tests.csproj b/test/EFCore.Sqlite.Tests/EFCore.Sqlite.Tests.csproj
index 1d91e297752..fcdb5a6ff62 100644
--- a/test/EFCore.Sqlite.Tests/EFCore.Sqlite.Tests.csproj
+++ b/test/EFCore.Sqlite.Tests/EFCore.Sqlite.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Sqlite.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Tests/EFCore.Tests.csproj b/test/EFCore.Tests/EFCore.Tests.csproj
index 97e2a70fb7a..941f580d001 100644
--- a/test/EFCore.Tests/EFCore.Tests.csproj
+++ b/test/EFCore.Tests/EFCore.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Tests
Microsoft.EntityFrameworkCore
diff --git a/test/EFCore.Tests/Storage/PhysicalAddressToBytesConverterTest.cs b/test/EFCore.Tests/Storage/PhysicalAddressToBytesConverterTest.cs
index 8aa11bd4464..047d3ea6a0a 100644
--- a/test/EFCore.Tests/Storage/PhysicalAddressToBytesConverterTest.cs
+++ b/test/EFCore.Tests/Storage/PhysicalAddressToBytesConverterTest.cs
@@ -56,11 +56,9 @@ public static IEnumerable Data
new object[] { "1D-4E-55-D6-92-73-D6" },
new object[] { "24-80-B7-38-4A-68-D6" },
new object[] { "1B-AB-DF-C7-3D-6B" },
-#if NET5_0
new object[] { "1D:4E:55:D6:92:73" },
new object[] { "24:80:B7:38:4A:68" },
new object[] { "1B:AB:DF:C7:3D:6B" },
-#endif
new object[] { "1D4E55D69273" },
new object[] { "1BABDFC73D6B" },
new object[] { "0459D099E185" },
diff --git a/test/EFCore.Tests/Storage/PhysicalAddressToStringConverterTest.cs b/test/EFCore.Tests/Storage/PhysicalAddressToStringConverterTest.cs
index b8f051c77b0..82abf38f98b 100644
--- a/test/EFCore.Tests/Storage/PhysicalAddressToStringConverterTest.cs
+++ b/test/EFCore.Tests/Storage/PhysicalAddressToStringConverterTest.cs
@@ -70,11 +70,9 @@ public static IEnumerable Data
new object[] { "1D-4E-55-D6-92-73-D6" },
new object[] { "24-80-B7-38-4A-68-D6" },
new object[] { "04-59-D0-99-E1-85" },
-#if NET5_0
new object[] { "1D:4E:55:D6:92:73" },
new object[] { "24:80:B7:38:4A:68" },
new object[] { "04:59:D0:99:E1:85" },
-#endif
new object[] { "1D4E55D69273" },
new object[] { "2480B7384A68" },
new object[] { "0459D099E185" },
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
index a515f6863ea..45a5310a61a 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
$(DefineConstants);E_SQLITE3
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
index eb2f6086a3f..93e6f74661f 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.e_sqlcipher.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
$(DefineConstants);E_SQLCIPHER
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
index 13e3baf36f0..23876c27817 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.sqlite3.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
$(DefineConstants);SQLITE3
diff --git a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
index d737a5df060..6e7753dc77e 100644
--- a/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
+++ b/test/Microsoft.Data.Sqlite.Tests/Microsoft.Data.Sqlite.winsqlite3.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
$(DefineConstants);WINSQLITE3
diff --git a/test/dotnet-ef.Tests/dotnet-ef.Tests.csproj b/test/dotnet-ef.Tests/dotnet-ef.Tests.csproj
index 9a9b0aeaa1d..643afbd08b7 100644
--- a/test/dotnet-ef.Tests/dotnet-ef.Tests.csproj
+++ b/test/dotnet-ef.Tests/dotnet-ef.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Tools
diff --git a/test/ef.Tests/ef.Tests.csproj b/test/ef.Tests/ef.Tests.csproj
index 85631f36ce4..80f4f5a91b2 100644
--- a/test/ef.Tests/ef.Tests.csproj
+++ b/test/ef.Tests/ef.Tests.csproj
@@ -1,7 +1,7 @@
- $(StandardTestTfms)
+ net5.0
Microsoft.EntityFrameworkCore.Tools