diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
index 9846d9fd3d6..2cfad91bad0 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
@@ -32,11 +33,12 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public CosmosQueryableMethodTranslatingExpressionVisitor(
+ [NotNull] QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
IModel model,
ISqlExpressionFactory sqlExpressionFactory,
IMemberTranslatorProvider memberTranslatorProvider,
IMethodCallTranslatorProvider methodCallTranslatorProvider)
- : base(subquery: false)
+ : base(dependencies, subquery: false)
{
_model = model;
_sqlExpressionFactory = sqlExpressionFactory;
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs
index 6732a77a209..50571bb3c90 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.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 JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
@@ -14,6 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
///
public class CosmosQueryableMethodTranslatingExpressionVisitorFactory : IQueryableMethodTranslatingExpressionVisitorFactory
{
+ private readonly QueryableMethodTranslatingExpressionVisitorDependencies _dependencies;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly IMemberTranslatorProvider _memberTranslatorProvider;
private readonly IMethodCallTranslatorProvider _methodCallTranslatorProvider;
@@ -25,10 +27,12 @@ public class CosmosQueryableMethodTranslatingExpressionVisitorFactory : IQueryab
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public CosmosQueryableMethodTranslatingExpressionVisitorFactory(
+ [NotNull] QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
ISqlExpressionFactory sqlExpressionFactory,
IMemberTranslatorProvider memberTranslatorProvider,
IMethodCallTranslatorProvider methodCallTranslatorProvider)
{
+ _dependencies = dependencies;
_sqlExpressionFactory = sqlExpressionFactory;
_memberTranslatorProvider = memberTranslatorProvider;
_methodCallTranslatorProvider = methodCallTranslatorProvider;
@@ -43,6 +47,7 @@ public CosmosQueryableMethodTranslatingExpressionVisitorFactory(
public virtual QueryableMethodTranslatingExpressionVisitor Create(IModel model)
{
return new CosmosQueryableMethodTranslatingExpressionVisitor(
+ _dependencies,
model,
_sqlExpressionFactory,
_memberTranslatorProvider,
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
index 873900f1e9e..816250589f8 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
@@ -43,10 +43,10 @@ public class CosmosShapedQueryCompilingExpressionVisitor : ShapedQueryCompilingE
///
public CosmosShapedQueryCompilingExpressionVisitor(
QueryCompilationContext queryCompilationContext,
- IEntityMaterializerSource entityMaterializerSource,
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies,
ISqlExpressionFactory sqlExpressionFactory,
IQuerySqlGeneratorFactory querySqlGeneratorFactory)
- : base(queryCompilationContext, entityMaterializerSource)
+ : base(queryCompilationContext, dependencies)
{
_sqlExpressionFactory = sqlExpressionFactory;
_querySqlGeneratorFactory = querySqlGeneratorFactory;
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitorFactory.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitorFactory.cs
index 483ddf075eb..e68a29036be 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitorFactory.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitorFactory.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 Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
@@ -14,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
///
public class CosmosShapedQueryCompilingExpressionVisitorFactory : IShapedQueryCompilingExpressionVisitorFactory
{
- private readonly IEntityMaterializerSource _entityMaterializerSource;
+ private readonly ShapedQueryCompilingExpressionVisitorDependencies _dependencies;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
@@ -24,11 +23,12 @@ public class CosmosShapedQueryCompilingExpressionVisitorFactory : IShapedQueryCo
/// 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 CosmosShapedQueryCompilingExpressionVisitorFactory(IEntityMaterializerSource entityMaterializerSource,
+ public CosmosShapedQueryCompilingExpressionVisitorFactory(
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies,
ISqlExpressionFactory sqlExpressionFactory,
IQuerySqlGeneratorFactory querySqlGeneratorFactory)
{
- _entityMaterializerSource = entityMaterializerSource;
+ _dependencies = dependencies;
_sqlExpressionFactory = sqlExpressionFactory;
_querySqlGeneratorFactory = querySqlGeneratorFactory;
}
@@ -42,7 +42,7 @@ public CosmosShapedQueryCompilingExpressionVisitorFactory(IEntityMaterializerSou
public virtual ShapedQueryCompilingExpressionVisitor Create(QueryCompilationContext queryCompilationContext)
=> new CosmosShapedQueryCompilingExpressionVisitor(
queryCompilationContext,
- _entityMaterializerSource,
+ _dependencies,
_sqlExpressionFactory,
_querySqlGeneratorFactory);
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
index 5c94db0b269..c973c4aa18a 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs
@@ -17,8 +17,10 @@ public class InMemoryQueryableMethodTranslatingExpressionVisitor : QueryableMeth
private readonly InMemoryProjectionBindingExpressionVisitor _projectionBindingExpressionVisitor;
private readonly IModel _model;
- public InMemoryQueryableMethodTranslatingExpressionVisitor(IModel model)
- : base(subquery: false)
+ public InMemoryQueryableMethodTranslatingExpressionVisitor(
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
+ IModel model)
+ : base(dependencies, subquery: false)
{
_expressionTranslator = new InMemoryExpressionTranslatingExpressionVisitor(this);
_projectionBindingExpressionVisitor = new InMemoryProjectionBindingExpressionVisitor(this, _expressionTranslator);
@@ -26,9 +28,10 @@ public InMemoryQueryableMethodTranslatingExpressionVisitor(IModel model)
}
public InMemoryQueryableMethodTranslatingExpressionVisitor(
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
IModel model,
InMemoryExpressionTranslatingExpressionVisitor expressionTranslator)
- : base(subquery: true)
+ : base(dependencies, subquery: true)
{
_expressionTranslator = expressionTranslator;
_projectionBindingExpressionVisitor = new InMemoryProjectionBindingExpressionVisitor(this, expressionTranslator);
@@ -41,8 +44,9 @@ private static Type CreateTransparentIdentifierType(Type outerType, Type innerTy
public override ShapedQueryExpression TranslateSubquery(Expression expression)
{
return (ShapedQueryExpression)new InMemoryQueryableMethodTranslatingExpressionVisitor(
- _model,
- _expressionTranslator)
+ Dependencies,
+ _model,
+ _expressionTranslator)
.Visit(expression);
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs
index cbaa18fcf85..4ad98f686bb 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitorFactory.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 JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
@@ -8,7 +9,15 @@ namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
public class InMemoryQueryableMethodTranslatingExpressionVisitorFactory : IQueryableMethodTranslatingExpressionVisitorFactory
{
+ private readonly QueryableMethodTranslatingExpressionVisitorDependencies _dependencies;
+
+ public InMemoryQueryableMethodTranslatingExpressionVisitorFactory(
+ [NotNull] QueryableMethodTranslatingExpressionVisitorDependencies dependencies)
+ {
+ _dependencies = dependencies;
+ }
+
public virtual QueryableMethodTranslatingExpressionVisitor Create(IModel model)
- => new InMemoryQueryableMethodTranslatingExpressionVisitor(model);
+ => new InMemoryQueryableMethodTranslatingExpressionVisitor(_dependencies, model);
}
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitor.cs
index 5f3607ff398..7dfd50d02f1 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitor.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitor.cs
@@ -26,8 +26,8 @@ private static readonly ConstructorInfo _valueBufferConstructor
public InMemoryShapedQueryCompilingExpressionVisitor(
QueryCompilationContext queryCompilationContext,
- IEntityMaterializerSource entityMaterializerSource)
- : base(queryCompilationContext, entityMaterializerSource)
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies)
+ : base(queryCompilationContext, dependencies)
{
_contextType = queryCompilationContext.ContextType;
_logger = queryCompilationContext.Logger;
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs
index cafca00480c..a14f31d592f 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryExpressionVisitorFactory.cs
@@ -1,26 +1,21 @@
// 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 Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
public class InMemoryShapedQueryCompilingExpressionVisitorFactory : IShapedQueryCompilingExpressionVisitorFactory
{
- private readonly IEntityMaterializerSource _entityMaterializerSource;
+ private readonly ShapedQueryCompilingExpressionVisitorDependencies _dependencies;
- public InMemoryShapedQueryCompilingExpressionVisitorFactory(IEntityMaterializerSource entityMaterializerSource)
+ public InMemoryShapedQueryCompilingExpressionVisitorFactory(ShapedQueryCompilingExpressionVisitorDependencies dependencies)
{
- _entityMaterializerSource = entityMaterializerSource;
+ _dependencies = dependencies;
}
public virtual ShapedQueryCompilingExpressionVisitor Create(QueryCompilationContext queryCompilationContext)
- {
- return new InMemoryShapedQueryCompilingExpressionVisitor(
- queryCompilationContext,
- _entityMaterializerSource);
- }
+ => new InMemoryShapedQueryCompilingExpressionVisitor(queryCompilationContext, _dependencies);
}
}
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizer.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizer.cs
index 6bb2c2c5bff..a0c7a548306 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizer.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizer.cs
@@ -8,6 +8,11 @@ namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
public class InMemoryShapedQueryOptimizer : ShapedQueryOptimizer
{
+ public InMemoryShapedQueryOptimizer(ShapedQueryOptimizerDependencies dependencies)
+ : base(dependencies)
+ {
+ }
+
public override Expression Visit(Expression query)
{
query = base.Visit(query);
diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizerFactory.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizerFactory.cs
index 25392ddd9a5..aecdb6ddd40 100644
--- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizerFactory.cs
+++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryOptimizerFactory.cs
@@ -7,9 +7,16 @@ namespace Microsoft.EntityFrameworkCore.InMemory.Query.Internal
{
public class InMemoryShapedQueryOptimizerFactory : IShapedQueryOptimizerFactory
{
+ private readonly ShapedQueryOptimizerDependencies _dependencies;
+
+ public InMemoryShapedQueryOptimizerFactory(ShapedQueryOptimizerDependencies dependencies)
+ {
+ _dependencies = dependencies;
+ }
+
public virtual ShapedQueryOptimizer Create(QueryCompilationContext queryCompilationContext)
{
- return new InMemoryShapedQueryOptimizer();
+ return new InMemoryShapedQueryOptimizer(_dependencies);
}
}
}
diff --git a/src/EFCore.InMemory/ValueGeneration/Internal/IInMemoryIntegerValueGenerator.cs b/src/EFCore.InMemory/ValueGeneration/Internal/IInMemoryIntegerValueGenerator.cs
new file mode 100644
index 00000000000..c4aaf136c89
--- /dev/null
+++ b/src/EFCore.InMemory/ValueGeneration/Internal/IInMemoryIntegerValueGenerator.cs
@@ -0,0 +1,22 @@
+// 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.
+
+namespace Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal
+{
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public interface IInMemoryIntegerValueGenerator
+ {
+ ///
+ /// 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.
+ ///
+ void Bump(object[] row);
+ }
+}
diff --git a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs
index 2fe350d73f8..001323b1d24 100644
--- a/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs
+++ b/src/EFCore.InMemory/ValueGeneration/Internal/InMemoryIntegerValueGenerator.cs
@@ -9,23 +9,6 @@
namespace Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal
{
- ///
- /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
- /// the same compatibility standards as public APIs. It may be changed or removed without notice in
- /// any release. You should only use it directly in your code with extreme caution and knowing that
- /// doing so can result in application failures when updating to a new Entity Framework Core release.
- ///
- public interface IInMemoryIntegerValueGenerator
- {
- ///
- /// 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.
- ///
- void Bump(object[] row);
- }
-
///
/// 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
diff --git a/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs b/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs
index 8e69f2e4078..720b0ab64b9 100644
--- a/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs
+++ b/src/EFCore.Relational/Infrastructure/EntityFrameworkRelationalServicesBuilder.cs
@@ -183,7 +183,11 @@ public override EntityFrameworkServicesBuilder TryAddCoreServices()
.AddDependencySingleton()
.AddDependencySingleton()
.AddDependencySingleton()
- .AddDependencySingleton()
+ .AddDependencySingleton()
+ .AddDependencySingleton()
+ .AddDependencySingleton()
+ .AddDependencySingleton()
+ .AddDependencySingleton()
.AddDependencyScoped()
.AddDependencyScoped()
.AddDependencyScoped()
@@ -193,6 +197,7 @@ public override EntityFrameworkServicesBuilder TryAddCoreServices()
.AddDependencyScoped()
.AddDependencyScoped()
.AddDependencyScoped()
+ .AddDependencyScoped()
.AddDependencyScoped();
return base.TryAddCoreServices();
diff --git a/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs b/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs
index 0f9d5743cd4..e22651fa522 100644
--- a/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs
+++ b/src/EFCore.Relational/Query/Internal/QuerySqlGeneratorFactory.cs
@@ -1,28 +1,18 @@
// 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 Microsoft.EntityFrameworkCore.Storage;
-
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class QuerySqlGeneratorFactory : IQuerySqlGeneratorFactory
{
- private readonly IRelationalCommandBuilderFactory _commandBuilderFactory;
- private readonly ISqlGenerationHelper _sqlGenerationHelper;
+ private readonly SqlExpressionVisitorDependencies _dependencies;
- public QuerySqlGeneratorFactory(
- IRelationalCommandBuilderFactory commandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
+ public QuerySqlGeneratorFactory(SqlExpressionVisitorDependencies dependencies)
{
- _commandBuilderFactory = commandBuilderFactory;
- _sqlGenerationHelper = sqlGenerationHelper;
+ _dependencies = dependencies;
}
public virtual QuerySqlGenerator Create()
- {
- return new QuerySqlGenerator(
- _commandBuilderFactory,
- _sqlGenerationHelper);
- }
+ => new QuerySqlGenerator(_dependencies);
}
}
diff --git a/src/EFCore.Relational/Query/Internal/RelationalQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalQueryableMethodTranslatingExpressionVisitorFactory.cs
index c0eba591b5c..ed4ca3ac47f 100644
--- a/src/EFCore.Relational/Query/Internal/RelationalQueryableMethodTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.Relational/Query/Internal/RelationalQueryableMethodTranslatingExpressionVisitorFactory.cs
@@ -7,23 +7,21 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class RelationalQueryableMethodTranslatingExpressionVisitorFactory : IQueryableMethodTranslatingExpressionVisitorFactory
{
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IRelationalSqlTranslatingExpressionVisitorFactory _relationalSqlTranslatingExpressionVisitorFactory;
+ private readonly QueryableMethodTranslatingExpressionVisitorDependencies _dependencies;
+ private readonly RelationalQueryableMethodTranslatingExpressionVisitorDependencies _relationalDependencies;
public RelationalQueryableMethodTranslatingExpressionVisitorFactory(
- IRelationalSqlTranslatingExpressionVisitorFactory relationalSqlTranslatingExpressionVisitorFactory,
- ISqlExpressionFactory sqlExpressionFactory)
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
+ RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies)
{
- _sqlExpressionFactory = sqlExpressionFactory;
- _relationalSqlTranslatingExpressionVisitorFactory = relationalSqlTranslatingExpressionVisitorFactory;
+ _dependencies = dependencies;
+ _relationalDependencies = relationalDependencies;
}
public virtual QueryableMethodTranslatingExpressionVisitor Create(IModel model)
- {
- return new RelationalQueryableMethodTranslatingExpressionVisitor(
- model,
- _relationalSqlTranslatingExpressionVisitorFactory,
- _sqlExpressionFactory);
- }
+ => new RelationalQueryableMethodTranslatingExpressionVisitor(
+ _dependencies,
+ _relationalDependencies,
+ model);
}
}
diff --git a/src/EFCore.Relational/Query/Internal/RelationalShapedQueryExpressionVisitorFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalShapedQueryExpressionVisitorFactory.cs
index b8a8a2f0da6..41b333c109e 100644
--- a/src/EFCore.Relational/Query/Internal/RelationalShapedQueryExpressionVisitorFactory.cs
+++ b/src/EFCore.Relational/Query/Internal/RelationalShapedQueryExpressionVisitorFactory.cs
@@ -1,37 +1,27 @@
// 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 Microsoft.EntityFrameworkCore.Storage;
-
namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class RelationalShapedQueryCompilingExpressionVisitorFactory : IShapedQueryCompilingExpressionVisitorFactory
{
- private readonly IEntityMaterializerSource _entityMaterializerSource;
- private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IParameterNameGeneratorFactory _parameterNameGeneratorFactory;
+ private readonly ShapedQueryCompilingExpressionVisitorDependencies _dependencies;
+ private readonly RelationalShapedQueryCompilingExpressionVisitorDependencies _relationalDependencies;
public RelationalShapedQueryCompilingExpressionVisitorFactory(
- IEntityMaterializerSource entityMaterializerSource,
- IQuerySqlGeneratorFactory querySqlGeneratorFactory,
- ISqlExpressionFactory sqlExpressionFactory,
- IParameterNameGeneratorFactory parameterNameGeneratorFactory)
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies,
+ RelationalShapedQueryCompilingExpressionVisitorDependencies relationalDependencies)
{
- _entityMaterializerSource = entityMaterializerSource;
- _querySqlGeneratorFactory = querySqlGeneratorFactory;
- _sqlExpressionFactory = sqlExpressionFactory;
- _parameterNameGeneratorFactory = parameterNameGeneratorFactory;
+ _dependencies = dependencies;
+ _relationalDependencies = relationalDependencies;
}
public virtual ShapedQueryCompilingExpressionVisitor Create(QueryCompilationContext queryCompilationContext)
{
return new RelationalShapedQueryCompilingExpressionVisitor(
queryCompilationContext,
- _entityMaterializerSource,
- _querySqlGeneratorFactory,
- _sqlExpressionFactory,
- _parameterNameGeneratorFactory);
+ _dependencies,
+ _relationalDependencies);
}
}
}
diff --git a/src/EFCore.Relational/Query/Internal/RelationalShapedQueryOptimizingExpressionVisitorsFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalShapedQueryOptimizingExpressionVisitorsFactory.cs
index 096ab687ca6..be41735927e 100644
--- a/src/EFCore.Relational/Query/Internal/RelationalShapedQueryOptimizingExpressionVisitorsFactory.cs
+++ b/src/EFCore.Relational/Query/Internal/RelationalShapedQueryOptimizingExpressionVisitorsFactory.cs
@@ -6,16 +6,27 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class RelationalShapedQueryOptimizerFactory : IShapedQueryOptimizerFactory
{
- protected virtual ISqlExpressionFactory SqlExpressionFactory { get; private set; }
+ private readonly ShapedQueryOptimizerDependencies _dependencies;
+ private readonly RelationalShapedQueryOptimizerDependencies _relationalDependencies;
- public RelationalShapedQueryOptimizerFactory(ISqlExpressionFactory sqlExpressionFactory)
+ public RelationalShapedQueryOptimizerFactory(
+ ShapedQueryOptimizerDependencies dependencies,
+ RelationalShapedQueryOptimizerDependencies relationalDependencies,
+ ISqlExpressionFactory sqlExpressionFactory)
{
+ _dependencies = dependencies;
+ _relationalDependencies = relationalDependencies;
SqlExpressionFactory = sqlExpressionFactory;
}
+ protected virtual ISqlExpressionFactory SqlExpressionFactory { get; }
+
public virtual ShapedQueryOptimizer Create(QueryCompilationContext queryCompilationContext)
{
- return new RelationalShapedQueryOptimizer(queryCompilationContext, SqlExpressionFactory);
+ return new RelationalShapedQueryOptimizer(
+ _dependencies,
+ _relationalDependencies,
+ queryCompilationContext);
}
}
}
diff --git a/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorDependencies.cs b/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..8c64275ec91
--- /dev/null
+++ b/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorDependencies.cs
@@ -0,0 +1,108 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means a single instance
+ /// is used by many instances. The implementation must be thread-safe.
+ /// This service cannot depend on services registered as .
+ ///
+ ///
+ public sealed class RelationalSqlTranslatingExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public RelationalSqlTranslatingExpressionVisitorDependencies(
+ [NotNull] ISqlExpressionFactory sqlExpressionFactory,
+ [NotNull] IMemberTranslatorProvider memberTranslatorProvider,
+ [NotNull] IMethodCallTranslatorProvider methodCallTranslatorProvider)
+ {
+ Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
+ Check.NotNull(memberTranslatorProvider, nameof(memberTranslatorProvider));
+ Check.NotNull(methodCallTranslatorProvider, nameof(methodCallTranslatorProvider));
+
+ SqlExpressionFactory = sqlExpressionFactory;
+ MemberTranslatorProvider = memberTranslatorProvider;
+ MethodCallTranslatorProvider = methodCallTranslatorProvider;
+ }
+
+ ///
+ /// The expression factory..
+ ///
+ public ISqlExpressionFactory SqlExpressionFactory { get; }
+
+ ///
+ /// The member translation provider.
+ ///
+ public IMemberTranslatorProvider MemberTranslatorProvider { get; }
+
+ ///
+ /// The method-call translation provider.
+ ///
+ public IMethodCallTranslatorProvider MethodCallTranslatorProvider { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalSqlTranslatingExpressionVisitorDependencies With([NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ => new RelationalSqlTranslatingExpressionVisitorDependencies(sqlExpressionFactory, MemberTranslatorProvider, MethodCallTranslatorProvider);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalSqlTranslatingExpressionVisitorDependencies With([NotNull] IMemberTranslatorProvider memberTranslatorProvider)
+ => new RelationalSqlTranslatingExpressionVisitorDependencies(SqlExpressionFactory, memberTranslatorProvider, MethodCallTranslatorProvider);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalSqlTranslatingExpressionVisitorDependencies With([NotNull] IMethodCallTranslatorProvider methodCallTranslatorProvider)
+ => new RelationalSqlTranslatingExpressionVisitorDependencies(SqlExpressionFactory, MemberTranslatorProvider, methodCallTranslatorProvider);
+ }
+}
diff --git a/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorFactory.cs b/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorFactory.cs
index e36b2994c12..7c8cae5828d 100644
--- a/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.Relational/Query/Internal/RelationalSqlTranslatingExpressionVisitorFactory.cs
@@ -1,125 +1,19 @@
// 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.Collections.Generic;
using JetBrains.Annotations;
-using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Utilities;
-using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.EntityFrameworkCore.Query
{
- ///
- ///
- /// Service dependencies parameter class for
- ///
- ///
- /// This type is typically used by database providers (and other extensions). It is generally
- /// not used in application code.
- ///
- ///
- /// Do not construct instances of this class directly from either provider or application code as the
- /// constructor signature may change as new dependencies are added. Instead, use this type in
- /// your constructor so that an instance will be created and injected automatically by the
- /// dependency injection container. To create an instance with some dependent services replaced,
- /// first resolve the object from the dependency injection container, then replace selected
- /// services using the 'With...' methods. Do not call the constructor at any point in this process.
- ///
- ///
- /// The service lifetime is . This means a single instance
- /// is used by many instances. The implementation must be thread-safe.
- /// This service cannot depend on services registered as .
- ///
- ///
- public sealed class RelationalSqlTranslatingExpressionVisitorFactoryDependencies
- {
- ///
- ///
- /// Creates the service dependencies parameter object for a .
- ///
- ///
- /// Do not call this constructor directly from either provider or application code as it may change
- /// as new dependencies are added. Instead, use this type in your constructor so that an instance
- /// will be created and injected automatically by the dependency injection container. To create
- /// an instance with some dependent services replaced, first resolve the object from the dependency
- /// injection container, then replace selected services using the 'With...' methods. Do not call
- /// the constructor at any point in this process.
- ///
- ///
- /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
- /// the same compatibility standards as public APIs. It may be changed or removed without notice in
- /// any release. You should only use it directly in your code with extreme caution and knowing that
- /// doing so can result in application failures when updating to a new Entity Framework Core release.
- ///
- ///
- [EntityFrameworkInternal]
- public RelationalSqlTranslatingExpressionVisitorFactoryDependencies(
- [NotNull] ISqlExpressionFactory sqlExpressionFactory,
- [NotNull] IMemberTranslatorProvider memberTranslatorProvider,
- [NotNull] IMethodCallTranslatorProvider methodCallTranslatorProvider)
- {
- Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
- Check.NotNull(memberTranslatorProvider, nameof(memberTranslatorProvider));
- Check.NotNull(methodCallTranslatorProvider, nameof(methodCallTranslatorProvider));
-
- SqlExpressionFactory = sqlExpressionFactory;
- MemberTranslatorProvider = memberTranslatorProvider;
- MethodCallTranslatorProvider = methodCallTranslatorProvider;
- }
-
- ///
- /// The expression factory..
- ///
- public ISqlExpressionFactory SqlExpressionFactory { get; }
-
- ///
- /// The member translation provider.
- ///
- public IMemberTranslatorProvider MemberTranslatorProvider { get; }
-
- ///
- /// The method-call translation provider.
- ///
- public IMethodCallTranslatorProvider MethodCallTranslatorProvider { get; }
-
- ///
- /// Clones this dependency parameter object with one service replaced.
- ///
- /// A replacement for the current dependency of this type.
- /// A new parameter object with the given service replaced.
- public RelationalSqlTranslatingExpressionVisitorFactoryDependencies With([NotNull] ISqlExpressionFactory sqlExpressionFactory)
- => new RelationalSqlTranslatingExpressionVisitorFactoryDependencies(sqlExpressionFactory, MemberTranslatorProvider, MethodCallTranslatorProvider);
-
- ///
- /// Clones this dependency parameter object with one service replaced.
- ///
- /// A replacement for the current dependency of this type.
- /// A new parameter object with the given service replaced.
- public RelationalSqlTranslatingExpressionVisitorFactoryDependencies With([NotNull] IMemberTranslatorProvider memberTranslatorProvider)
- => new RelationalSqlTranslatingExpressionVisitorFactoryDependencies(SqlExpressionFactory, memberTranslatorProvider, MethodCallTranslatorProvider);
-
- ///
- /// Clones this dependency parameter object with one service replaced.
- ///
- /// A replacement for the current dependency of this type.
- /// A new parameter object with the given service replaced.
- public RelationalSqlTranslatingExpressionVisitorFactoryDependencies With([NotNull] IMethodCallTranslatorProvider methodCallTranslatorProvider)
- => new RelationalSqlTranslatingExpressionVisitorFactoryDependencies(SqlExpressionFactory, MemberTranslatorProvider, methodCallTranslatorProvider);
- }
-
public class RelationalSqlTranslatingExpressionVisitorFactory : IRelationalSqlTranslatingExpressionVisitorFactory
{
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IMemberTranslatorProvider _memberTranslatorProvider;
- private readonly IMethodCallTranslatorProvider _methodCallTranslatorProvider;
+ private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies;
public RelationalSqlTranslatingExpressionVisitorFactory(
- [NotNull] RelationalSqlTranslatingExpressionVisitorFactoryDependencies dependencies)
+ [NotNull] RelationalSqlTranslatingExpressionVisitorDependencies dependencies)
{
- _sqlExpressionFactory = dependencies.SqlExpressionFactory;
- _memberTranslatorProvider = dependencies.MemberTranslatorProvider;
- _methodCallTranslatorProvider = dependencies.MethodCallTranslatorProvider;
+ _dependencies = dependencies;
}
public virtual RelationalSqlTranslatingExpressionVisitor Create(
@@ -127,11 +21,9 @@ public virtual RelationalSqlTranslatingExpressionVisitor Create(
QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
{
return new RelationalSqlTranslatingExpressionVisitor(
+ _dependencies,
model,
- queryableMethodTranslatingExpressionVisitor,
- _sqlExpressionFactory,
- _memberTranslatorProvider,
- _methodCallTranslatorProvider);
+ queryableMethodTranslatingExpressionVisitor);
}
}
}
diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs
index dd404b7417c..fd03893b588 100644
--- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs
+++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs
@@ -38,12 +38,11 @@ public class QuerySqlGenerator : SqlExpressionVisitor
{ ExpressionType.Or, " | " }
};
- public QuerySqlGenerator(
- IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
+ public QuerySqlGenerator(SqlExpressionVisitorDependencies dependencies)
+ : base(dependencies)
{
- _relationalCommandBuilderFactory = relationalCommandBuilderFactory;
- _sqlGenerationHelper = sqlGenerationHelper;
+ _relationalCommandBuilderFactory = dependencies.RelationalCommandBuilderFactory;
+ _sqlGenerationHelper = dependencies.SqlGenerationHelper;
}
public virtual IRelationalCommand GetCommand(SelectExpression selectExpression)
diff --git a/src/EFCore.Relational/Query/RelationalQueryContext.cs b/src/EFCore.Relational/Query/RelationalQueryContext.cs
index c820f1cdbe2..6601923169c 100644
--- a/src/EFCore.Relational/Query/RelationalQueryContext.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryContext.cs
@@ -14,7 +14,7 @@ public class RelationalQueryContext : QueryContext
{
///
///
- /// Creates a new instance.
+ /// Creates a new instance.
///
///
/// This type is typically used by database providers (and other extensions). It is generally
@@ -22,28 +22,30 @@ public class RelationalQueryContext : QueryContext
///
///
/// The dependencies to use.
- /// The relational connection.
- /// A factory for creating the execution strategy to use.
+ /// The relational-specific dependencies to use.
public RelationalQueryContext(
[NotNull] QueryContextDependencies dependencies,
- [NotNull] IRelationalConnection connection,
- [NotNull] IExecutionStrategyFactory executionStrategyFactory)
+ [NotNull] RelationalQueryContextDependencies relationalDependencies)
: base(dependencies)
{
- Check.NotNull(connection, nameof(connection));
- Check.NotNull(executionStrategyFactory, nameof(executionStrategyFactory));
+ Check.NotNull(relationalDependencies, nameof(relationalDependencies));
- Connection = connection;
- ExecutionStrategyFactory = executionStrategyFactory;
+ RelationalDependencies = relationalDependencies;
}
+ ///
+ /// Relational-specific dependencies.
+ ///
+ protected virtual RelationalQueryContextDependencies RelationalDependencies { get; }
+
///
/// Gets the active relational connection.
///
///
/// The connection.
///
- public virtual IRelationalConnection Connection { get; }
+ public virtual IRelationalConnection Connection
+ => RelationalDependencies.RelationalConnection;
///
/// The execution strategy factory.
@@ -51,6 +53,7 @@ public RelationalQueryContext(
///
/// The execution strategy factory.
///
- public virtual IExecutionStrategyFactory ExecutionStrategyFactory { get; }
+ public virtual IExecutionStrategyFactory ExecutionStrategyFactory
+ => RelationalDependencies.ExecutionStrategyFactory;
}
}
diff --git a/src/EFCore.Relational/Query/RelationalQueryContextDependencies.cs b/src/EFCore.Relational/Query/RelationalQueryContextDependencies.cs
new file mode 100644
index 00000000000..8253e6ebe75
--- /dev/null
+++ b/src/EFCore.Relational/Query/RelationalQueryContextDependencies.cs
@@ -0,0 +1,94 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class RelationalQueryContextDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public RelationalQueryContextDependencies(
+ [NotNull] IRelationalConnection relationalConnection,
+ [NotNull] IExecutionStrategyFactory executionStrategyFactory)
+ {
+ Check.NotNull(relationalConnection, nameof(relationalConnection));
+ Check.NotNull(executionStrategyFactory, nameof(executionStrategyFactory));
+
+ RelationalConnection = relationalConnection;
+ ExecutionStrategyFactory = executionStrategyFactory;
+ }
+
+ ///
+ /// The connection.
+ ///
+ public IRelationalConnection RelationalConnection { get; }
+
+ ///
+ /// The execution strategy.
+ ///
+ public IExecutionStrategyFactory ExecutionStrategyFactory { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalQueryContextDependencies With([NotNull] IRelationalConnection relationalConnection)
+ => new RelationalQueryContextDependencies(relationalConnection, ExecutionStrategyFactory);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalQueryContextDependencies With([NotNull] IExecutionStrategyFactory executionStrategyFactory)
+ => new RelationalQueryContextDependencies(RelationalConnection, executionStrategyFactory);
+ }
+}
diff --git a/src/EFCore.Relational/Query/RelationalQueryContextFactory.cs b/src/EFCore.Relational/Query/RelationalQueryContextFactory.cs
index fb1ca93b3d4..1cf096875b3 100644
--- a/src/EFCore.Relational/Query/RelationalQueryContextFactory.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryContextFactory.cs
@@ -20,31 +20,32 @@ namespace Microsoft.EntityFrameworkCore.Query
///
public class RelationalQueryContextFactory : QueryContextFactory
{
- private readonly IRelationalConnection _connection;
-
///
/// Creates a new instance using the given dependencies.
///
/// The dependencies to use.
- /// The connection to use.
- /// A factory for the execution strategy to use.
+ /// Relational-specific dependencies.
public RelationalQueryContextFactory(
[NotNull] QueryContextDependencies dependencies,
- [NotNull] IRelationalConnection connection,
- [NotNull] IExecutionStrategyFactory executionStrategyFactory)
+ [NotNull] RelationalQueryContextDependencies relationalDependencies)
: base(dependencies)
{
- _connection = connection;
- ExecutionStrategyFactory = executionStrategyFactory;
+ RelationalDependencies = relationalDependencies;
}
+ ///
+ /// Relational-specific dependencies.
+ ///
+ protected virtual RelationalQueryContextDependencies RelationalDependencies { get; }
+
///
/// The execution strategy factory.
///
///
/// The execution strategy factory.
///
- protected virtual IExecutionStrategyFactory ExecutionStrategyFactory { get; }
+ protected virtual IExecutionStrategyFactory ExecutionStrategyFactory
+ => RelationalDependencies.ExecutionStrategyFactory;
///
/// Creates a new .
@@ -53,6 +54,6 @@ public RelationalQueryContextFactory(
/// A QueryContext.
///
public override QueryContext Create()
- => new RelationalQueryContext(Dependencies, _connection, ExecutionStrategyFactory);
+ => new RelationalQueryContext(Dependencies, RelationalDependencies);
}
}
diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
index dc067f30acc..2a6632948b4 100644
--- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
@@ -26,24 +26,31 @@ public class RelationalQueryableMethodTranslatingExpressionVisitor : QueryableMe
private readonly ISqlExpressionFactory _sqlExpressionFactory;
public RelationalQueryableMethodTranslatingExpressionVisitor(
- IModel model,
- IRelationalSqlTranslatingExpressionVisitorFactory relationalSqlTranslatingExpressionVisitorFactory,
- ISqlExpressionFactory sqlExpressionFactory)
- : base(subquery: false)
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
+ RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies,
+ IModel model)
+ : base(dependencies, subquery: false)
{
- _sqlTranslator = relationalSqlTranslatingExpressionVisitorFactory.Create(model, this);
+ RelationalDependencies = relationalDependencies;
+
+ var sqlExpressionFactory = relationalDependencies.SqlExpressionFactory;
+ _sqlTranslator = relationalDependencies.RelationalSqlTranslatingExpressionVisitorFactory.Create(model, this);
_weakEntityExpandingExpressionVisitor = new WeakEntityExpandingExpressionVisitor(_sqlTranslator, sqlExpressionFactory);
_projectionBindingExpressionVisitor = new RelationalProjectionBindingExpressionVisitor(this, _sqlTranslator);
_model = model;
_sqlExpressionFactory = sqlExpressionFactory;
}
+ protected virtual RelationalQueryableMethodTranslatingExpressionVisitorDependencies RelationalDependencies { get; }
+
private RelationalQueryableMethodTranslatingExpressionVisitor(
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
+ RelationalQueryableMethodTranslatingExpressionVisitorDependencies relationalDependencies,
IModel model,
RelationalSqlTranslatingExpressionVisitor sqlTranslator,
WeakEntityExpandingExpressionVisitor weakEntityExpandingExpressionVisitor,
ISqlExpressionFactory sqlExpressionFactory)
- : base(subquery: true)
+ : base(dependencies, subquery: true)
{
_model = model;
_sqlTranslator = sqlTranslator;
@@ -70,6 +77,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
public override ShapedQueryExpression TranslateSubquery(Expression expression)
=> (ShapedQueryExpression)new RelationalQueryableMethodTranslatingExpressionVisitor(
+ Dependencies,
+ RelationalDependencies,
_model,
_sqlTranslator,
_weakEntityExpandingExpressionVisitor,
diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependencies.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..5890186fff5
--- /dev/null
+++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependencies.cs
@@ -0,0 +1,92 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means a single instance
+ /// is used by many instances. The implementation must be thread-safe.
+ /// This service cannot depend on services registered as .
+ ///
+ ///
+ public sealed class RelationalQueryableMethodTranslatingExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public RelationalQueryableMethodTranslatingExpressionVisitorDependencies(
+ [NotNull] IRelationalSqlTranslatingExpressionVisitorFactory relationalSqlTranslatingExpressionVisitorFactory,
+ [NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ {
+ Check.NotNull(relationalSqlTranslatingExpressionVisitorFactory, nameof(relationalSqlTranslatingExpressionVisitorFactory));
+ Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
+
+ RelationalSqlTranslatingExpressionVisitorFactory = relationalSqlTranslatingExpressionVisitorFactory;
+ SqlExpressionFactory = sqlExpressionFactory;
+ }
+
+ ///
+ /// The SQL-translating expression visitor factory.
+ ///
+ public IRelationalSqlTranslatingExpressionVisitorFactory RelationalSqlTranslatingExpressionVisitorFactory { get; }
+
+ ///
+ /// The SQL expression factory.
+ ///
+ public ISqlExpressionFactory SqlExpressionFactory { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalQueryableMethodTranslatingExpressionVisitorDependencies With([NotNull] IRelationalSqlTranslatingExpressionVisitorFactory relationalSqlTranslatingExpressionVisitorFactory)
+ => new RelationalQueryableMethodTranslatingExpressionVisitorDependencies(relationalSqlTranslatingExpressionVisitorFactory, SqlExpressionFactory);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalQueryableMethodTranslatingExpressionVisitorDependencies With([NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ => new RelationalQueryableMethodTranslatingExpressionVisitorDependencies(RelationalSqlTranslatingExpressionVisitorFactory, sqlExpressionFactory);
+ }
+}
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs
index db9eb8bed74..e2a2cd40ace 100644
--- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs
@@ -8,35 +8,30 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
-using Microsoft.EntityFrameworkCore.Storage;
namespace Microsoft.EntityFrameworkCore.Query
{
public partial class RelationalShapedQueryCompilingExpressionVisitor : ShapedQueryCompilingExpressionVisitor
{
- private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IParameterNameGeneratorFactory _parameterNameGeneratorFactory;
private readonly Type _contextType;
private readonly IDiagnosticsLogger _logger;
private readonly ISet _tags;
public RelationalShapedQueryCompilingExpressionVisitor(
QueryCompilationContext queryCompilationContext,
- IEntityMaterializerSource entityMaterializerSource,
- IQuerySqlGeneratorFactory querySqlGeneratorFactory,
- ISqlExpressionFactory sqlExpressionFactory,
- IParameterNameGeneratorFactory parameterNameGeneratorFactory)
- : base(queryCompilationContext, entityMaterializerSource)
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies,
+ RelationalShapedQueryCompilingExpressionVisitorDependencies relationalDependencies)
+ : base(queryCompilationContext, dependencies)
{
- _querySqlGeneratorFactory = querySqlGeneratorFactory;
- _sqlExpressionFactory = sqlExpressionFactory;
- _parameterNameGeneratorFactory = parameterNameGeneratorFactory;
+ RelationalDependencies = relationalDependencies;
+
_contextType = queryCompilationContext.ContextType;
_logger = queryCompilationContext.Logger;
_tags = queryCompilationContext.Tags;
}
+ protected virtual RelationalShapedQueryCompilingExpressionVisitorDependencies RelationalDependencies { get; }
+
protected override Expression VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
{
var selectExpression = (SelectExpression)shapedQueryExpression.QueryExpression;
@@ -73,9 +68,9 @@ protected override Expression VisitShapedQueryExpression(ShapedQueryExpression s
? typeof(AsyncQueryingEnumerable<>)
: typeof(QueryingEnumerable<>)).MakeGenericType(shaperLambda.ReturnType).GetConstructors()[0],
Expression.Convert(QueryCompilationContext.QueryContextParameter, typeof(RelationalQueryContext)),
- Expression.Constant(_querySqlGeneratorFactory),
- Expression.Constant(_sqlExpressionFactory),
- Expression.Constant(_parameterNameGeneratorFactory),
+ Expression.Constant(RelationalDependencies.QuerySqlGeneratorFactory),
+ Expression.Constant(RelationalDependencies.SqlExpressionFactory),
+ Expression.Constant(RelationalDependencies.ParameterNameGeneratorFactory),
Expression.Constant(selectExpression),
Expression.Constant(shaperLambda.Compile()),
Expression.Constant(_contextType),
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitorDependencies.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..00fc6bed5d1
--- /dev/null
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitorDependencies.cs
@@ -0,0 +1,119 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class RelationalShapedQueryCompilingExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public RelationalShapedQueryCompilingExpressionVisitorDependencies(
+ [NotNull] IQuerySqlGeneratorFactory querySqlGeneratorFactory,
+ [NotNull] ISqlExpressionFactory sqlExpressionFactory,
+ [NotNull] IParameterNameGeneratorFactory parameterNameGeneratorFactory)
+ {
+ Check.NotNull(querySqlGeneratorFactory, nameof(querySqlGeneratorFactory));
+ Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
+ Check.NotNull(parameterNameGeneratorFactory, nameof(parameterNameGeneratorFactory));
+
+ QuerySqlGeneratorFactory = querySqlGeneratorFactory;
+ SqlExpressionFactory = sqlExpressionFactory;
+ ParameterNameGeneratorFactory = parameterNameGeneratorFactory;
+ }
+
+ ///
+ /// The SQL generator factory.
+ ///
+ public IQuerySqlGeneratorFactory QuerySqlGeneratorFactory { get; }
+
+ ///
+ /// The SQL expression factory.
+ ///
+ public ISqlExpressionFactory SqlExpressionFactory { get; }
+
+ ///
+ /// The parameter name-generator factory.
+ ///
+ public IParameterNameGeneratorFactory ParameterNameGeneratorFactory { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalShapedQueryCompilingExpressionVisitorDependencies With([NotNull] IQuerySqlGeneratorFactory querySqlGeneratorFactory)
+ => new RelationalShapedQueryCompilingExpressionVisitorDependencies(
+ querySqlGeneratorFactory,
+ SqlExpressionFactory,
+ ParameterNameGeneratorFactory);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalShapedQueryCompilingExpressionVisitorDependencies With([NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ => new RelationalShapedQueryCompilingExpressionVisitorDependencies(
+ QuerySqlGeneratorFactory,
+ sqlExpressionFactory,
+ ParameterNameGeneratorFactory);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalShapedQueryCompilingExpressionVisitorDependencies With([NotNull] IParameterNameGeneratorFactory parameterNameGeneratorFactory)
+ => new RelationalShapedQueryCompilingExpressionVisitorDependencies(
+ QuerySqlGeneratorFactory,
+ SqlExpressionFactory,
+ parameterNameGeneratorFactory);
+ }
+}
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryOptimizer.cs b/src/EFCore.Relational/Query/RelationalShapedQueryOptimizer.cs
index cce3887758a..267a9d92931 100644
--- a/src/EFCore.Relational/Query/RelationalShapedQueryOptimizer.cs
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryOptimizer.cs
@@ -4,20 +4,27 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Query.Internal;
+using Microsoft.EntityFrameworkCore.Storage;
namespace Microsoft.EntityFrameworkCore.Query
{
public class RelationalShapedQueryOptimizer : ShapedQueryOptimizer
{
public RelationalShapedQueryOptimizer(
- QueryCompilationContext queryCompilationContext,
- ISqlExpressionFactory sqlExpressionFactory)
+ ShapedQueryOptimizerDependencies dependencies,
+ RelationalShapedQueryOptimizerDependencies relationalDependencies,
+ QueryCompilationContext queryCompilationContext)
+ : base(dependencies)
{
+ RelationalDependencies = relationalDependencies;
UseRelationalNulls = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).UseRelationalNulls;
- SqlExpressionFactory = sqlExpressionFactory;
+ SqlExpressionFactory = relationalDependencies.SqlExpressionFactory;
}
+ protected virtual RelationalShapedQueryOptimizerDependencies RelationalDependencies { get; }
+
protected virtual ISqlExpressionFactory SqlExpressionFactory { get; }
+
protected virtual bool UseRelationalNulls { get; }
public override Expression Visit(Expression query)
diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryOptimizerDependencies.cs b/src/EFCore.Relational/Query/RelationalShapedQueryOptimizerDependencies.cs
new file mode 100644
index 00000000000..29efada8329
--- /dev/null
+++ b/src/EFCore.Relational/Query/RelationalShapedQueryOptimizerDependencies.cs
@@ -0,0 +1,76 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class RelationalShapedQueryOptimizerDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public RelationalShapedQueryOptimizerDependencies(
+ [NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ {
+ SqlExpressionFactory = sqlExpressionFactory;
+ Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
+ }
+
+ ///
+ /// The SQL expression factory.
+ ///
+ public ISqlExpressionFactory SqlExpressionFactory { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public RelationalShapedQueryOptimizerDependencies With([NotNull] ISqlExpressionFactory sqlExpressionFactory)
+ => new RelationalShapedQueryOptimizerDependencies(sqlExpressionFactory);
+ }
+}
diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
index e4fa084e736..f70fa4b44e2 100644
--- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
@@ -5,7 +5,6 @@
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
-using System.Reflection;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
@@ -20,25 +19,23 @@ public class RelationalSqlTranslatingExpressionVisitor : ExpressionVisitor
private readonly IModel _model;
private readonly QueryableMethodTranslatingExpressionVisitor _queryableMethodTranslatingExpressionVisitor;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IMemberTranslatorProvider _memberTranslatorProvider;
- private readonly IMethodCallTranslatorProvider _methodCallTranslatorProvider;
private readonly SqlTypeMappingVerifyingExpressionVisitor _sqlVerifyingExpressionVisitor;
public RelationalSqlTranslatingExpressionVisitor(
+ RelationalSqlTranslatingExpressionVisitorDependencies dependencies,
IModel model,
- QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor,
- ISqlExpressionFactory sqlExpressionFactory,
- IMemberTranslatorProvider memberTranslatorProvider,
- IMethodCallTranslatorProvider methodCallTranslatorProvider)
+ QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
{
+ Dependencies = dependencies;
+
_model = model;
_queryableMethodTranslatingExpressionVisitor = queryableMethodTranslatingExpressionVisitor;
- _sqlExpressionFactory = sqlExpressionFactory;
- _memberTranslatorProvider = memberTranslatorProvider;
- _methodCallTranslatorProvider = methodCallTranslatorProvider;
+ _sqlExpressionFactory = dependencies.SqlExpressionFactory;
_sqlVerifyingExpressionVisitor = new SqlTypeMappingVerifyingExpressionVisitor();
}
+ protected virtual RelationalSqlTranslatingExpressionVisitorDependencies Dependencies { get; }
+
public virtual SqlExpression Translate(Expression expression)
{
var result = Visit(expression);
@@ -178,7 +175,7 @@ protected override Expression VisitMember(MemberExpression memberExpression)
return TranslationFailed(memberExpression.Expression, innerExpression)
? null
- : _memberTranslatorProvider.Translate((SqlExpression)innerExpression, memberExpression.Member, memberExpression.Type);
+ : Dependencies.MemberTranslatorProvider.Translate((SqlExpression)innerExpression, memberExpression.Member, memberExpression.Type);
}
private bool TryBindMember(Expression source, MemberIdentity member, out Expression expression)
@@ -349,7 +346,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
arguments[i] = (SqlExpression)argument;
}
- return _methodCallTranslatorProvider.Translate(_model, (SqlExpression)@object, methodCallExpression.Method, arguments);
+ return Dependencies.MethodCallTranslatorProvider.Translate(_model, (SqlExpression)@object, methodCallExpression.Method, arguments);
}
private static Expression TryRemoveImplicitConvert(Expression expression)
diff --git a/src/EFCore.Relational/Query/SqlExpressionVisitor.cs b/src/EFCore.Relational/Query/SqlExpressionVisitor.cs
index 3672d4525e7..160e04eb19c 100644
--- a/src/EFCore.Relational/Query/SqlExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/SqlExpressionVisitor.cs
@@ -3,11 +3,20 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
+using Microsoft.EntityFrameworkCore.Utilities;
namespace Microsoft.EntityFrameworkCore.Query
{
public abstract class SqlExpressionVisitor : ExpressionVisitor
{
+
+ protected SqlExpressionVisitor(SqlExpressionVisitorDependencies dependencies)
+ {
+ Dependencies = dependencies;
+ }
+
+ protected virtual SqlExpressionVisitorDependencies Dependencies { get; }
+
protected override Expression VisitExtension(Expression extensionExpression)
{
switch (extensionExpression)
diff --git a/src/EFCore.Relational/Query/SqlExpressionVisitorDependencies.cs b/src/EFCore.Relational/Query/SqlExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..b254c10cbd6
--- /dev/null
+++ b/src/EFCore.Relational/Query/SqlExpressionVisitorDependencies.cs
@@ -0,0 +1,93 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means a single instance
+ /// is used by many instances. The implementation must be thread-safe.
+ /// This service cannot depend on services registered as .
+ ///
+ ///
+ public sealed class SqlExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public SqlExpressionVisitorDependencies(
+ [NotNull] IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
+ [NotNull] ISqlGenerationHelper sqlGenerationHelper)
+ {
+ Check.NotNull(relationalCommandBuilderFactory, nameof(relationalCommandBuilderFactory));
+ Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));
+
+ RelationalCommandBuilderFactory = relationalCommandBuilderFactory;
+ SqlGenerationHelper = sqlGenerationHelper;
+ }
+
+ ///
+ /// The command-builder factory.
+ ///
+ public IRelationalCommandBuilderFactory RelationalCommandBuilderFactory { get; }
+
+ ///
+ /// SQL generation helpers.
+ ///
+ public ISqlGenerationHelper SqlGenerationHelper { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public SqlExpressionVisitorDependencies With([NotNull] IRelationalCommandBuilderFactory relationalCommandBuilderFactory)
+ => new SqlExpressionVisitorDependencies(relationalCommandBuilderFactory, SqlGenerationHelper);
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public SqlExpressionVisitorDependencies With([NotNull] ISqlGenerationHelper sqlGenerationHelper)
+ => new SqlExpressionVisitorDependencies(RelationalCommandBuilderFactory, sqlGenerationHelper);
+ }
+}
diff --git a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs
index 34eab9c2287..1a60fb9b087 100644
--- a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs
@@ -14,7 +14,10 @@ public class SearchConditionConvertingExpressionVisitor : SqlExpressionVisitor
private bool _isSearchCondition;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
- public SearchConditionConvertingExpressionVisitor(ISqlExpressionFactory sqlExpressionFactory)
+ public SearchConditionConvertingExpressionVisitor(
+ SqlExpressionVisitorDependencies dependencies,
+ ISqlExpressionFactory sqlExpressionFactory)
+ : base(dependencies)
{
_sqlExpressionFactory = sqlExpressionFactory;
}
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
index 89ca2cb8759..ecc8ab712c9 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
@@ -10,10 +10,8 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerQuerySqlGenerator : QuerySqlGenerator
{
- public SqlServerQuerySqlGenerator(
- IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
- : base(relationalCommandBuilderFactory, sqlGenerationHelper)
+ public SqlServerQuerySqlGenerator(SqlExpressionVisitorDependencies dependencies)
+ : base(dependencies)
{
}
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGeneratorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGeneratorFactory.cs
index 332c2c38393..caac945776f 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGeneratorFactory.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGeneratorFactory.cs
@@ -2,24 +2,19 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.EntityFrameworkCore.Query;
-using Microsoft.EntityFrameworkCore.Storage;
namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerQuerySqlGeneratorFactory : IQuerySqlGeneratorFactory
{
- private readonly IRelationalCommandBuilderFactory _commandBuilderFactory;
- private readonly ISqlGenerationHelper _sqlGenerationHelper;
+ private readonly SqlExpressionVisitorDependencies _dependencies;
- public SqlServerQuerySqlGeneratorFactory(
- IRelationalCommandBuilderFactory commandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
+ public SqlServerQuerySqlGeneratorFactory(SqlExpressionVisitorDependencies dependencies)
{
- _commandBuilderFactory = commandBuilderFactory;
- _sqlGenerationHelper = sqlGenerationHelper;
+ _dependencies = dependencies;
}
public virtual QuerySqlGenerator Create()
- => new SqlServerQuerySqlGenerator(_commandBuilderFactory, _sqlGenerationHelper);
+ => new SqlServerQuerySqlGenerator(_dependencies);
}
}
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitors.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitors.cs
index 33a1d8097a3..584b4eca0b4 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitors.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitors.cs
@@ -8,17 +8,22 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerShapedQueryOptimizer : RelationalShapedQueryOptimizer
{
+ private readonly SqlExpressionVisitorDependencies _sqlExpressionVisitorDependencies;
+
public SqlServerShapedQueryOptimizer(
- QueryCompilationContext queryCompilationContext,
- ISqlExpressionFactory sqlExpressionFactory)
- : base(queryCompilationContext, sqlExpressionFactory)
+ ShapedQueryOptimizerDependencies dependencies,
+ RelationalShapedQueryOptimizerDependencies relationalDependencies,
+ SqlExpressionVisitorDependencies sqlExpressionVisitorDependencies,
+ QueryCompilationContext queryCompilationContext)
+ : base(dependencies, relationalDependencies, queryCompilationContext)
{
+ _sqlExpressionVisitorDependencies = sqlExpressionVisitorDependencies;
}
public override Expression Visit(Expression query)
{
query = base.Visit(query);
- query = new SearchConditionConvertingExpressionVisitor(SqlExpressionFactory).Visit(query);
+ query = new SearchConditionConvertingExpressionVisitor(_sqlExpressionVisitorDependencies, SqlExpressionFactory).Visit(query);
query = new SqlExpressionOptimizingVisitor(SqlExpressionFactory, UseRelationalNulls).Visit(query);
return query;
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitorsFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitorsFactory.cs
index 7b0fb6b2ca0..e96ec42937e 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitorsFactory.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerShapedQueryOptimizingExpressionVisitorsFactory.cs
@@ -7,16 +7,25 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerShapedQueryOptimizerFactory : IShapedQueryOptimizerFactory
{
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
+ private readonly SqlExpressionVisitorDependencies _sqlExpressionVisitorDependencies;
+ private readonly ShapedQueryOptimizerDependencies _dependencies;
+ private readonly RelationalShapedQueryOptimizerDependencies _relationalDependencies;
- public SqlServerShapedQueryOptimizerFactory(ISqlExpressionFactory sqlExpressionFactory)
+ public SqlServerShapedQueryOptimizerFactory(
+ SqlExpressionVisitorDependencies sqlExpressionVisitorDependencies,
+ ShapedQueryOptimizerDependencies dependencies,
+ RelationalShapedQueryOptimizerDependencies relationalDependencies)
{
- _sqlExpressionFactory = sqlExpressionFactory;
+ _sqlExpressionVisitorDependencies = sqlExpressionVisitorDependencies;
+ _dependencies = dependencies;
+ _relationalDependencies = relationalDependencies;
}
public virtual ShapedQueryOptimizer Create(QueryCompilationContext queryCompilationContext)
- {
- return new SqlServerShapedQueryOptimizer(queryCompilationContext, _sqlExpressionFactory);
- }
+ => new SqlServerShapedQueryOptimizer(
+ _dependencies,
+ _relationalDependencies,
+ _sqlExpressionVisitorDependencies,
+ queryCompilationContext);
}
}
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
index 1ba2aeaffbb..498539c95d9 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitor.cs
@@ -34,14 +34,12 @@ private static readonly HashSet _arithmeticOperatorTypes
private readonly ISqlExpressionFactory _sqlExpressionFactory;
public SqlServerSqlTranslatingExpressionVisitor(
+ RelationalSqlTranslatingExpressionVisitorDependencies dependencies,
IModel model,
- QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor,
- ISqlExpressionFactory sqlExpressionFactory,
- IMemberTranslatorProvider memberTranslatorProvider,
- IMethodCallTranslatorProvider methodCallTranslatorProvider)
- : base(model, queryableMethodTranslatingExpressionVisitor, sqlExpressionFactory, memberTranslatorProvider, methodCallTranslatorProvider)
+ QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
+ : base(dependencies, model, queryableMethodTranslatingExpressionVisitor)
{
- _sqlExpressionFactory = sqlExpressionFactory;
+ _sqlExpressionFactory = dependencies.SqlExpressionFactory;
}
protected override Expression VisitBinary(BinaryExpression binaryExpression)
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitorFactory.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitorFactory.cs
index a29038b7169..6d91e6e1040 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlTranslatingExpressionVisitorFactory.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 JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
@@ -8,30 +9,20 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal
{
public class SqlServerSqlTranslatingExpressionVisitorFactory : IRelationalSqlTranslatingExpressionVisitorFactory
{
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly IMemberTranslatorProvider _memberTranslatorProvider;
- private readonly IMethodCallTranslatorProvider _methodCallTranslatorProvider;
+ private readonly RelationalSqlTranslatingExpressionVisitorDependencies _dependencies;
public SqlServerSqlTranslatingExpressionVisitorFactory(
- ISqlExpressionFactory sqlExpressionFactory,
- IMemberTranslatorProvider memberTranslatorProvider,
- IMethodCallTranslatorProvider methodCallTranslatorProvider)
+ [NotNull] RelationalSqlTranslatingExpressionVisitorDependencies dependencies)
{
- _sqlExpressionFactory = sqlExpressionFactory;
- _memberTranslatorProvider = memberTranslatorProvider;
- _methodCallTranslatorProvider = methodCallTranslatorProvider;
+ _dependencies = dependencies;
}
public virtual RelationalSqlTranslatingExpressionVisitor Create(
IModel model,
QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
- {
- return new SqlServerSqlTranslatingExpressionVisitor(
+ => new SqlServerSqlTranslatingExpressionVisitor(
+ _dependencies,
model,
- queryableMethodTranslatingExpressionVisitor,
- _sqlExpressionFactory,
- _memberTranslatorProvider,
- _methodCallTranslatorProvider);
- }
+ queryableMethodTranslatingExpressionVisitor);
}
}
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs
index e2baf00e439..eac7b9b2a4f 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs
@@ -12,10 +12,8 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
{
public class SqliteQuerySqlGenerator : QuerySqlGenerator
{
- public SqliteQuerySqlGenerator(
- IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
- : base(relationalCommandBuilderFactory, sqlGenerationHelper)
+ public SqliteQuerySqlGenerator(SqlExpressionVisitorDependencies dependencies)
+ : base(dependencies)
{
}
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs
index 41fd0243719..b1d7fdcc399 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGeneratorFactory.cs
@@ -2,24 +2,19 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.EntityFrameworkCore.Query;
-using Microsoft.EntityFrameworkCore.Storage;
namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
{
public class SqliteQuerySqlGeneratorFactory : IQuerySqlGeneratorFactory
{
- private readonly IRelationalCommandBuilderFactory _commandBuilderFactory;
- private readonly ISqlGenerationHelper _sqlGenerationHelper;
+ private readonly SqlExpressionVisitorDependencies _dependencies;
- public SqliteQuerySqlGeneratorFactory(
- IRelationalCommandBuilderFactory commandBuilderFactory,
- ISqlGenerationHelper sqlGenerationHelper)
+ public SqliteQuerySqlGeneratorFactory(SqlExpressionVisitorDependencies dependencies)
{
- _commandBuilderFactory = commandBuilderFactory;
- _sqlGenerationHelper = sqlGenerationHelper;
+ _dependencies = dependencies;
}
public virtual QuerySqlGenerator Create()
- => new SqliteQuerySqlGenerator(_commandBuilderFactory, _sqlGenerationHelper);
+ => new SqliteQuerySqlGenerator(_dependencies);
}
}
diff --git a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
index 854cd935e46..6fd0f7a451e 100644
--- a/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Sqlite.Core/Query/Internal/SqliteSqlTranslatingExpressionVisitor.cs
@@ -78,12 +78,10 @@ private static readonly IReadOnlyDictionary new SqliteSqlTranslatingExpressionVisitor(
+ _dependencies,
model,
- queryableMethodTranslatingExpressionVisitor,
- _sqlExpressionFactory,
- _memberTranslatorProvider,
- _methodCallTranslatorProvider);
- }
+ queryableMethodTranslatingExpressionVisitor);
}
}
diff --git a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs
index 2e280ad3d9e..93a69924d70 100644
--- a/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs
+++ b/src/EFCore/Infrastructure/EntityFrameworkServicesBuilder.cs
@@ -281,7 +281,11 @@ public virtual EntityFrameworkServicesBuilder TryAddCoreServices()
.AddDependencySingleton()
.AddDependencySingleton()
.AddDependencySingleton()
+ .AddDependencySingleton()
+ .AddDependencySingleton()
.AddDependencyScoped()
+ .AddDependencyScoped()
+ .AddDependencyScoped()
.AddDependencyScoped()
.AddDependencyScoped()
.AddDependencyScoped()
diff --git a/src/EFCore/Query/Internal/QueryOptimizerFactory.cs b/src/EFCore/Query/Internal/QueryOptimizerFactory.cs
index 1d789453aa8..6a03b2fd441 100644
--- a/src/EFCore/Query/Internal/QueryOptimizerFactory.cs
+++ b/src/EFCore/Query/Internal/QueryOptimizerFactory.cs
@@ -5,7 +5,14 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class QueryOptimizerFactory : IQueryOptimizerFactory
{
+ private readonly QueryOptimizerDependencies _dependencies;
+
+ public QueryOptimizerFactory(QueryOptimizerDependencies dependencies)
+ {
+ _dependencies = dependencies;
+ }
+
public virtual QueryOptimizer Create(QueryCompilationContext queryCompilationContext)
- => new QueryOptimizer(queryCompilationContext);
+ => new QueryOptimizer(_dependencies, queryCompilationContext);
}
}
diff --git a/src/EFCore/Query/Internal/ShapedQueryOptimizerFactory.cs b/src/EFCore/Query/Internal/ShapedQueryOptimizerFactory.cs
index 4617e9bd7a3..e9ae6684d6a 100644
--- a/src/EFCore/Query/Internal/ShapedQueryOptimizerFactory.cs
+++ b/src/EFCore/Query/Internal/ShapedQueryOptimizerFactory.cs
@@ -5,9 +5,16 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
{
public class ShapedQueryOptimizerFactory : IShapedQueryOptimizerFactory
{
+ private readonly ShapedQueryOptimizerDependencies _dependencies;
+
+ public ShapedQueryOptimizerFactory(ShapedQueryOptimizerDependencies dependencies)
+ {
+ _dependencies = dependencies;
+ }
+
public virtual ShapedQueryOptimizer Create(QueryCompilationContext queryCompilationContext)
{
- return new ShapedQueryOptimizer();
+ return new ShapedQueryOptimizer(_dependencies);
}
}
}
diff --git a/src/EFCore/Query/QueryOptimizer.cs b/src/EFCore/Query/QueryOptimizer.cs
index 1138dca54c4..513a35a9c39 100644
--- a/src/EFCore/Query/QueryOptimizer.cs
+++ b/src/EFCore/Query/QueryOptimizer.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Query.NavigationExpansion.Internal;
@@ -13,11 +14,16 @@ public class QueryOptimizer
{
private readonly QueryCompilationContext _queryCompilationContext;
- public QueryOptimizer(QueryCompilationContext queryCompilationContext)
+ public QueryOptimizer(
+ QueryOptimizerDependencies dependencies,
+ QueryCompilationContext queryCompilationContext)
{
+ Dependencies = dependencies;
_queryCompilationContext = queryCompilationContext;
}
+ protected virtual QueryOptimizerDependencies Dependencies { get; }
+
public virtual Expression Visit(Expression query)
{
query = new QueryMetadataExtractingExpressionVisitor(_queryCompilationContext).Visit(query);
diff --git a/src/EFCore/Query/QueryOptimizerDependencies.cs b/src/EFCore/Query/QueryOptimizerDependencies.cs
new file mode 100644
index 00000000000..2ef40ccfcce
--- /dev/null
+++ b/src/EFCore/Query/QueryOptimizerDependencies.cs
@@ -0,0 +1,58 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class QueryOptimizerDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public QueryOptimizerDependencies()
+ {
+ }
+ }
+}
diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
index e8237a6ef8a..69cb2513b1f 100644
--- a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitor.cs
@@ -6,8 +6,10 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query.NavigationExpansion.Internal;
+using Microsoft.EntityFrameworkCore.Utilities;
namespace Microsoft.EntityFrameworkCore.Query
{
@@ -15,11 +17,16 @@ public abstract class QueryableMethodTranslatingExpressionVisitor : ExpressionVi
{
private readonly bool _subquery;
- protected QueryableMethodTranslatingExpressionVisitor(bool subquery)
+ protected QueryableMethodTranslatingExpressionVisitor(
+ QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
+ bool subquery)
{
+ Dependencies = dependencies;
_subquery = subquery;
}
+ protected virtual QueryableMethodTranslatingExpressionVisitorDependencies Dependencies { get; }
+
protected override Expression VisitConstant(ConstantExpression constantExpression)
=> constantExpression.IsEntityQueryable()
? CreateShapedQueryExpression(((IQueryable)constantExpression.Value).ElementType)
diff --git a/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..68a8ef44455
--- /dev/null
+++ b/src/EFCore/Query/QueryableMethodTranslatingExpressionVisitorDependencies.cs
@@ -0,0 +1,57 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means a single instance
+ /// is used by many instances. The implementation must be thread-safe.
+ /// This service cannot depend on services registered as .
+ ///
+ ///
+ public sealed class QueryableMethodTranslatingExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public QueryableMethodTranslatingExpressionVisitorDependencies()
+ {
+ }
+ }
+}
diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
index 86fb5f879f3..877dc2f0056 100644
--- a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitor.cs
@@ -30,20 +30,25 @@ private static readonly MethodInfo _singleOrDefaultMethodInfo
private static readonly PropertyInfo _cancellationTokenMemberInfo
= typeof(QueryContext).GetProperty(nameof(QueryContext.CancellationToken));
- private readonly IEntityMaterializerSource _entityMaterializerSource;
private readonly Expression _cancellationTokenParameter;
private readonly EntityMaterializerInjectingExpressionVisitor _entityMaterializerInjectingExpressionVisitor;
protected ShapedQueryCompilingExpressionVisitor(
QueryCompilationContext queryCompilationContext,
- IEntityMaterializerSource entityMaterializerSource)
+ ShapedQueryCompilingExpressionVisitorDependencies dependencies)
{
- _entityMaterializerSource = entityMaterializerSource;
+ Dependencies = dependencies;
+
IsTracking = queryCompilationContext.IsTracking;
+
_entityMaterializerInjectingExpressionVisitor =
- new EntityMaterializerInjectingExpressionVisitor(entityMaterializerSource, IsTracking);
+ new EntityMaterializerInjectingExpressionVisitor(
+ dependencies.EntityMaterializerSource,
+ queryCompilationContext.IsTracking);
+
IsAsync = queryCompilationContext.IsAsync;
- if (IsAsync)
+
+ if (queryCompilationContext.IsAsync)
{
_cancellationTokenParameter = Expression.MakeMemberAccess(
QueryCompilationContext.QueryContextParameter,
@@ -51,6 +56,7 @@ protected ShapedQueryCompilingExpressionVisitor(
}
}
+ protected virtual ShapedQueryCompilingExpressionVisitorDependencies Dependencies { get; }
protected virtual bool IsTracking { get; }
diff --git a/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs
new file mode 100644
index 00000000000..30c398fd9a0
--- /dev/null
+++ b/src/EFCore/Query/ShapedQueryCompilingExpressionVisitorDependencies.cs
@@ -0,0 +1,77 @@
+// 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 JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class ShapedQueryCompilingExpressionVisitorDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public ShapedQueryCompilingExpressionVisitorDependencies(
+ [NotNull] IEntityMaterializerSource entityMaterializerSource)
+ {
+ Check.NotNull(entityMaterializerSource, nameof(entityMaterializerSource));
+
+ EntityMaterializerSource = entityMaterializerSource;
+ }
+
+ ///
+ /// The materializer source.
+ ///
+ public IEntityMaterializerSource EntityMaterializerSource { get; }
+
+ ///
+ /// Clones this dependency parameter object with one service replaced.
+ ///
+ /// A replacement for the current dependency of this type.
+ /// A new parameter object with the given service replaced.
+ public ShapedQueryCompilingExpressionVisitorDependencies With([NotNull] IEntityMaterializerSource entityMaterializerSource)
+ => new ShapedQueryCompilingExpressionVisitorDependencies(entityMaterializerSource);
+ }
+}
diff --git a/src/EFCore/Query/ShapedQueryOptimizer.cs b/src/EFCore/Query/ShapedQueryOptimizer.cs
index ac049c0696a..0c31ddc14d1 100644
--- a/src/EFCore/Query/ShapedQueryOptimizer.cs
+++ b/src/EFCore/Query/ShapedQueryOptimizer.cs
@@ -7,6 +7,13 @@ namespace Microsoft.EntityFrameworkCore.Query
{
public class ShapedQueryOptimizer
{
+ public ShapedQueryOptimizer(ShapedQueryOptimizerDependencies dependencies)
+ {
+ Dependencies = dependencies;
+ }
+
+ protected virtual ShapedQueryOptimizerDependencies Dependencies { get; }
+
public virtual Expression Visit(Expression query)
{
return query;
diff --git a/src/EFCore/Query/ShapedQueryOptimizerDependencies.cs b/src/EFCore/Query/ShapedQueryOptimizerDependencies.cs
new file mode 100644
index 00000000000..7deeea2b4ec
--- /dev/null
+++ b/src/EFCore/Query/ShapedQueryOptimizerDependencies.cs
@@ -0,0 +1,58 @@
+// 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 Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ ///
+ ///
+ /// Service dependencies parameter class for
+ ///
+ ///
+ /// This type is typically used by database providers (and other extensions). It is generally
+ /// not used in application code.
+ ///
+ ///
+ /// Do not construct instances of this class directly from either provider or application code as the
+ /// constructor signature may change as new dependencies are added. Instead, use this type in
+ /// your constructor so that an instance will be created and injected automatically by the
+ /// dependency injection container. To create an instance with some dependent services replaced,
+ /// first resolve the object from the dependency injection container, then replace selected
+ /// services using the 'With...' methods. Do not call the constructor at any point in this process.
+ ///
+ ///
+ /// The service lifetime is . This means that each
+ /// instance will use its own instance of this service.
+ /// The implementation may depend on other services registered with any lifetime.
+ /// The implementation does not need to be thread-safe.
+ ///
+ ///
+ public sealed class ShapedQueryOptimizerDependencies
+ {
+ ///
+ ///
+ /// Creates the service dependencies parameter object for a .
+ ///
+ ///
+ /// Do not call this constructor directly from either provider or application code as it may change
+ /// as new dependencies are added. Instead, use this type in your constructor so that an instance
+ /// will be created and injected automatically by the dependency injection container. To create
+ /// an instance with some dependent services replaced, first resolve the object from the dependency
+ /// injection container, then replace selected services using the 'With...' methods. Do not call
+ /// the constructor at any point in this process.
+ ///
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ ///
+ [EntityFrameworkInternal]
+ public ShapedQueryOptimizerDependencies()
+ {
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/Query/RelationalQueryContextDependenciesTest.cs b/test/EFCore.Relational.Tests/Query/RelationalQueryContextDependenciesTest.cs
new file mode 100644
index 00000000000..d52da4020fc
--- /dev/null
+++ b/test/EFCore.Relational.Tests/Query/RelationalQueryContextDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class RelationalQueryContextDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ RelationalTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependenciesTest.cs b/test/EFCore.Relational.Tests/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependenciesTest.cs
new file mode 100644
index 00000000000..208df1b1cb0
--- /dev/null
+++ b/test/EFCore.Relational.Tests/Query/RelationalQueryableMethodTranslatingExpressionVisitorDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class RelationalQueryableMethodTranslatingExpressionVisitorDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ RelationalTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/Query/RelationalShapedQueryCompilingExpressionVisitorDependenciesTest.cs b/test/EFCore.Relational.Tests/Query/RelationalShapedQueryCompilingExpressionVisitorDependenciesTest.cs
new file mode 100644
index 00000000000..6ee4e6d9fb5
--- /dev/null
+++ b/test/EFCore.Relational.Tests/Query/RelationalShapedQueryCompilingExpressionVisitorDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class RelationalShapedQueryCompilingExpressionVisitorDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ RelationalTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/Query/RelationalShapedQueryOptimizerDependenciesTest.cs b/test/EFCore.Relational.Tests/Query/RelationalShapedQueryOptimizerDependenciesTest.cs
new file mode 100644
index 00000000000..3074e727d81
--- /dev/null
+++ b/test/EFCore.Relational.Tests/Query/RelationalShapedQueryOptimizerDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class RelationalShapedQueryOptimizerDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ RelationalTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/Query/SqlExpressionVisitorDependenciesTest.cs b/test/EFCore.Relational.Tests/Query/SqlExpressionVisitorDependenciesTest.cs
new file mode 100644
index 00000000000..951160236e5
--- /dev/null
+++ b/test/EFCore.Relational.Tests/Query/SqlExpressionVisitorDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class SqlExpressionVisitorDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ RelationalTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorFactoryDependenciesTest.cs b/test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorDependenciesTest.cs
similarity index 77%
rename from test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorFactoryDependenciesTest.cs
rename to test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorDependenciesTest.cs
index 9f584dc3f67..776b7b39288 100644
--- a/test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorFactoryDependenciesTest.cs
+++ b/test/EFCore.Relational.Tests/RelationalSqlTranslatingExpressionVisitorDependenciesTest.cs
@@ -7,12 +7,12 @@
namespace Microsoft.EntityFrameworkCore
{
- public class RelationalSqlTranslatingExpressionVisitorFactoryDependenciesTest
+ public class RelationalSqlTranslatingExpressionVisitorDependenciesTest
{
[ConditionalFact]
public void Can_use_With_methods_to_clone_and_replace_service()
{
- RelationalTestHelpers.Instance.TestDependenciesClone();
+ RelationalTestHelpers.Instance.TestDependenciesClone();
}
}
}
diff --git a/test/EFCore.Tests/Query/QueryOptimizerDependenciesTest.cs b/test/EFCore.Tests/Query/QueryOptimizerDependenciesTest.cs
new file mode 100644
index 00000000000..3f2dc19011e
--- /dev/null
+++ b/test/EFCore.Tests/Query/QueryOptimizerDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class QueryOptimizerDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ InMemoryTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Tests/Query/QueryableMethodTranslatingExpressionVisitorDependenciesTest.cs b/test/EFCore.Tests/Query/QueryableMethodTranslatingExpressionVisitorDependenciesTest.cs
new file mode 100644
index 00000000000..e383022195f
--- /dev/null
+++ b/test/EFCore.Tests/Query/QueryableMethodTranslatingExpressionVisitorDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class QueryableMethodTranslatingExpressionVisitorDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ InMemoryTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Tests/Query/ShapedQueryCompilingExpressionVisitorDependenciesTest.cs b/test/EFCore.Tests/Query/ShapedQueryCompilingExpressionVisitorDependenciesTest.cs
new file mode 100644
index 00000000000..458d00d8cb2
--- /dev/null
+++ b/test/EFCore.Tests/Query/ShapedQueryCompilingExpressionVisitorDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class ShapedQueryCompilingExpressionVisitorDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ InMemoryTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}
diff --git a/test/EFCore.Tests/Query/ShapedQueryOptimizerDependenciesDependenciesTest.cs b/test/EFCore.Tests/Query/ShapedQueryOptimizerDependenciesDependenciesTest.cs
new file mode 100644
index 00000000000..a04fcb3da92
--- /dev/null
+++ b/test/EFCore.Tests/Query/ShapedQueryOptimizerDependenciesDependenciesTest.cs
@@ -0,0 +1,17 @@
+// 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 Microsoft.EntityFrameworkCore.TestUtilities;
+using Xunit;
+
+namespace Microsoft.EntityFrameworkCore.Query
+{
+ public class ShapedQueryOptimizerDependenciesDependenciesTest
+ {
+ [ConditionalFact]
+ public void Can_use_With_methods_to_clone_and_replace_service()
+ {
+ InMemoryTestHelpers.Instance.TestDependenciesClone();
+ }
+ }
+}