diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs
index f3e5c259847..cd46015679b 100644
--- a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs
+++ b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs
@@ -131,6 +131,14 @@ public static string JsonPropertyCollision(object? property1, object? property2,
public static string MissingOrderingInSelectExpression
=> GetString("MissingOrderingInSelectExpression");
+ ///
+ /// Cosmos container '{container1}' is referenced by the query, but '{container2}' is already being referenced. A query can only reference a single Cosmos container.
+ ///
+ public static string MultipleContainersReferencedInQuery(object? container1, object? container2)
+ => string.Format(
+ GetString("MultipleContainersReferencedInQuery", nameof(container1), nameof(container2)),
+ container1, container2);
+
///
/// Navigation '{entityType}.{navigationName}' doesn't point to an embedded entity.
///
diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.resx b/src/EFCore.Cosmos/Properties/CosmosStrings.resx
index b432bfe31a1..2417a7c1a77 100644
--- a/src/EFCore.Cosmos/Properties/CosmosStrings.resx
+++ b/src/EFCore.Cosmos/Properties/CosmosStrings.resx
@@ -198,6 +198,9 @@
'Reverse' could not be translated to the server because there is no ordering on the server side.
+
+ Cosmos container '{container1}' is referenced by the query, but '{container2}' is already being referenced. A query can only reference a single Cosmos container.
+
Navigation '{entityType}.{navigationName}' doesn't point to an embedded entity.
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContext.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContext.cs
index 49d99d3712d..1b0d35baf5d 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContext.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryCompilationContext.cs
@@ -12,6 +12,17 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
public class CosmosQueryCompilationContext(QueryCompilationContextDependencies dependencies, bool async)
: QueryCompilationContext(dependencies, async)
{
+ ///
+ /// The name of the Cosmos container against which this query will be executed.
+ ///
+ ///
+ /// 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 virtual string? CosmosContainer { get; internal set; }
+
///
/// 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.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
index 5b68e1c5798..73756688170 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs
@@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
///
public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethodTranslatingExpressionVisitor
{
- private readonly QueryCompilationContext _queryCompilationContext;
+ private readonly CosmosQueryCompilationContext _queryCompilationContext;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly ITypeMappingSource _typeMappingSource;
private readonly IMemberTranslatorProvider _memberTranslatorProvider;
@@ -31,7 +31,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethod
///
public CosmosQueryableMethodTranslatingExpressionVisitor(
QueryableMethodTranslatingExpressionVisitorDependencies dependencies,
- QueryCompilationContext queryCompilationContext,
+ CosmosQueryCompilationContext queryCompilationContext,
ISqlExpressionFactory sqlExpressionFactory,
ITypeMappingSource typeMappingSource,
IMemberTranslatorProvider memberTranslatorProvider,
@@ -258,13 +258,29 @@ protected override QueryableMethodTranslatingExpressionVisitor CreateSubqueryVis
protected override ShapedQueryExpression CreateShapedQueryExpression(IEntityType entityType)
=> CreateShapedQueryExpression(entityType, _sqlExpressionFactory.Select(entityType));
- private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType entityType, Expression queryExpression)
- => new(
+ private ShapedQueryExpression CreateShapedQueryExpression(IEntityType entityType, Expression queryExpression)
+ {
+ if (!entityType.IsOwned())
+ {
+ var cosmosContainer = entityType.GetContainer();
+ var existingContainer = _queryCompilationContext.CosmosContainer;
+ Check.DebugAssert(cosmosContainer is not null, "Non-owned entity type without a Cosmos container");
+
+ if (existingContainer is not null && existingContainer != cosmosContainer)
+ {
+ throw new InvalidOperationException(CosmosStrings.MultipleContainersReferencedInQuery(cosmosContainer, existingContainer));
+ }
+
+ _queryCompilationContext.CosmosContainer = cosmosContainer;
+ }
+
+ return new ShapedQueryExpression(
queryExpression,
new StructuralTypeShaperExpression(
entityType,
new ProjectionBindingExpression(queryExpression, new ProjectionMember(), typeof(ValueBuffer)),
false));
+ }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -304,7 +320,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent
}
var translation = _sqlExpressionFactory.Exists(subquery);
- var selectExpression = new SelectExpression(subquery.Container, translation);
+ var selectExpression = new SelectExpression(translation);
return source.Update(
selectExpression,
@@ -368,18 +384,17 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou
{
// Simplify x.Array.Contains[1] => ARRAY_CONTAINS(x.Array, 1) insert of IN+subquery
if (CosmosQueryUtils.TryExtractBareArray(source, out var array, ignoreOrderings: true)
- && TranslateExpression(item) is SqlExpression translatedItem
- && source.QueryExpression is SelectExpression { Container: var container })
+ && TranslateExpression(item) is SqlExpression translatedItem)
{
if (array is ArrayConstantExpression arrayConstant)
{
var inExpression = _sqlExpressionFactory.In(translatedItem, arrayConstant.Items);
- return source.Update(new SelectExpression(container, inExpression), source.ShaperExpression);
+ return source.Update(new SelectExpression(inExpression), source.ShaperExpression);
}
(translatedItem, array) = _sqlExpressionFactory.ApplyTypeMappingsOnItemAndArray(translatedItem, array);
var simplifiedTranslation = _sqlExpressionFactory.Function("ARRAY_CONTAINS", new[] { array, translatedItem }, typeof(bool));
- return source.UpdateQueryExpression(new SelectExpression(container, simplifiedTranslation));
+ return source.UpdateQueryExpression(new SelectExpression(simplifiedTranslation));
}
// TODO: Translation to IN, with scalars and with subquery
@@ -396,11 +411,10 @@ protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression sou
{
// Simplify x.Array.Count() => ARRAY_LENGTH(x.Array) instead of (SELECT COUNT(1) FROM i IN x.Array))
if (predicate is null
- && CosmosQueryUtils.TryExtractBareArray(source, out var array, ignoreOrderings: true)
- && source.QueryExpression is SelectExpression { Container: var container })
+ && CosmosQueryUtils.TryExtractBareArray(source, out var array, ignoreOrderings: true))
{
var simplifiedTranslation = _sqlExpressionFactory.Function("ARRAY_LENGTH", new[] { array }, typeof(int));
- return source.UpdateQueryExpression(new SelectExpression(container, simplifiedTranslation));
+ return source.UpdateQueryExpression(new SelectExpression(simplifiedTranslation));
}
var selectExpression = (SelectExpression)source.QueryExpression;
@@ -470,12 +484,11 @@ protected override ShapedQueryExpression TranslateDistinct(ShapedQueryExpression
// Simplify x.Array[1] => x.Array[1] (using the Cosmos array subscript operator) instead of a subquery with LIMIT/OFFSET
if (!returnDefault
&& CosmosQueryUtils.TryExtractBareArray(source, out var array, out var projectedScalarReference)
- && TranslateExpression(index) is { } translatedIndex
- && source.QueryExpression is SelectExpression { Container: var container })
+ && TranslateExpression(index) is { } translatedIndex)
{
var arrayIndex = _sqlExpressionFactory.ArrayIndex(
array, translatedIndex, projectedScalarReference.Type, projectedScalarReference.TypeMapping);
- return source.UpdateQueryExpression(new SelectExpression(container, arrayIndex));
+ return source.UpdateQueryExpression(new SelectExpression(arrayIndex));
}
// Note that Cosmos doesn't support OFFSET/LIMIT in subqueries, so this translation is for top-level entity querying only.
@@ -1252,8 +1265,7 @@ when methodCallExpression.TryGetIndexerArguments(_queryCompilationContext.Model,
var innerSelect = new SelectExpression(
[new ProjectionExpression(inlineArray, null!)],
sources: [],
- orderings: [],
- container: null!)
+ orderings: [])
{
UsesSingleValueProjection = true
};
@@ -1289,8 +1301,7 @@ [new ProjectionExpression(inlineArray, null!)],
var innerSelect = new SelectExpression(
[new ProjectionExpression(sqlParameterExpression, null!)],
sources: [],
- orderings: [],
- container: null!)
+ orderings: [])
{
UsesSingleValueProjection = true
};
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs
index f43f8fbe98b..b89f6d202ba 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitorFactory.cs
@@ -31,7 +31,7 @@ public class CosmosQueryableMethodTranslatingExpressionVisitorFactory(
public virtual QueryableMethodTranslatingExpressionVisitor Create(QueryCompilationContext queryCompilationContext)
=> new CosmosQueryableMethodTranslatingExpressionVisitor(
Dependencies,
- queryCompilationContext,
+ (CosmosQueryCompilationContext)queryCompilationContext,
sqlExpressionFactory,
typeMappingSource,
memberTranslatorProvider,
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs
index 8fcfe871c05..aa69ddf4524 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs
@@ -27,7 +27,8 @@ private sealed class QueryingEnumerable : IEnumerable, IAsyncEnumerable
private readonly Func _shaper;
private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory;
private readonly Type _contextType;
- private readonly PartitionKey _partitionKeyValue;
+ private readonly string _cosmosContainer;
+ private readonly PartitionKey _cosmosPartitionKeyValue;
private readonly IDiagnosticsLogger _queryLogger;
private readonly bool _standAloneStateManager;
private readonly bool _threadSafetyChecksEnabled;
@@ -39,6 +40,7 @@ public QueryingEnumerable(
SelectExpression selectExpression,
Func shaper,
Type contextType,
+ string cosmosContainer,
PartitionKey partitionKeyValueFromExtension,
bool standAloneStateManager,
bool threadSafetyChecksEnabled)
@@ -61,7 +63,8 @@ public QueryingEnumerable(
throw new InvalidOperationException(CosmosStrings.PartitionKeyMismatch(partitionKeyValueFromExtension, partitionKey));
}
- _partitionKeyValue = partitionKey != PartitionKey.None ? partitionKey : partitionKeyValueFromExtension;
+ _cosmosPartitionKeyValue = partitionKey != PartitionKey.None ? partitionKey : partitionKeyValueFromExtension;
+ _cosmosContainer = cosmosContainer;
}
public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default)
@@ -107,10 +110,10 @@ private sealed class Enumerator : IEnumerator
{
private readonly QueryingEnumerable _queryingEnumerable;
private readonly CosmosQueryContext _cosmosQueryContext;
- private readonly SelectExpression _selectExpression;
private readonly Func _shaper;
private readonly Type _contextType;
- private readonly PartitionKey _partitionKeyValue;
+ private readonly string _cosmosContainer;
+ private readonly PartitionKey _cosmosPartitionKeyValue;
private readonly IDiagnosticsLogger _queryLogger;
private readonly bool _standAloneStateManager;
private readonly IConcurrencyDetector _concurrencyDetector;
@@ -123,9 +126,9 @@ public Enumerator(QueryingEnumerable queryingEnumerable)
_queryingEnumerable = queryingEnumerable;
_cosmosQueryContext = queryingEnumerable._cosmosQueryContext;
_shaper = queryingEnumerable._shaper;
- _selectExpression = queryingEnumerable._selectExpression;
_contextType = queryingEnumerable._contextType;
- _partitionKeyValue = queryingEnumerable._partitionKeyValue;
+ _cosmosContainer = queryingEnumerable._cosmosContainer;
+ _cosmosPartitionKeyValue = queryingEnumerable._cosmosPartitionKeyValue;
_queryLogger = queryingEnumerable._queryLogger;
_standAloneStateManager = queryingEnumerable._standAloneStateManager;
_exceptionDetector = _cosmosQueryContext.ExceptionDetector;
@@ -156,8 +159,8 @@ public bool MoveNext()
_enumerator = _cosmosQueryContext.CosmosClient
.ExecuteSqlQuery(
- _selectExpression.Container,
- _partitionKeyValue,
+ _cosmosContainer,
+ _cosmosPartitionKeyValue,
sqlQuery)
.GetEnumerator();
_cosmosQueryContext.InitializeStateManager(_standAloneStateManager);
@@ -206,10 +209,10 @@ private sealed class AsyncEnumerator : IAsyncEnumerator
{
private readonly QueryingEnumerable _queryingEnumerable;
private readonly CosmosQueryContext _cosmosQueryContext;
- private readonly SelectExpression _selectExpression;
private readonly Func _shaper;
private readonly Type _contextType;
- private readonly PartitionKey _partitionKeyValue;
+ private readonly string _cosmosContainer;
+ private readonly PartitionKey _cosmosPartitionKeyValue;
private readonly IDiagnosticsLogger _queryLogger;
private readonly bool _standAloneStateManager;
private readonly CancellationToken _cancellationToken;
@@ -223,9 +226,9 @@ public AsyncEnumerator(QueryingEnumerable queryingEnumerable, CancellationTok
_queryingEnumerable = queryingEnumerable;
_cosmosQueryContext = queryingEnumerable._cosmosQueryContext;
_shaper = queryingEnumerable._shaper;
- _selectExpression = queryingEnumerable._selectExpression;
_contextType = queryingEnumerable._contextType;
- _partitionKeyValue = queryingEnumerable._partitionKeyValue;
+ _cosmosContainer = queryingEnumerable._cosmosContainer;
+ _cosmosPartitionKeyValue = queryingEnumerable._cosmosPartitionKeyValue;
_queryLogger = queryingEnumerable._queryLogger;
_standAloneStateManager = queryingEnumerable._standAloneStateManager;
_exceptionDetector = _cosmosQueryContext.ExceptionDetector;
@@ -254,8 +257,8 @@ public async ValueTask MoveNextAsync()
_enumerator = _cosmosQueryContext.CosmosClient
.ExecuteSqlQueryAsync(
- _selectExpression.Container,
- _partitionKeyValue,
+ _cosmosContainer,
+ _cosmosPartitionKeyValue,
sqlQuery)
.GetAsyncEnumerator(_cancellationToken);
_cosmosQueryContext.InitializeStateManager(_standAloneStateManager);
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs
index 948b67f22d4..420dc595df8 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs
@@ -22,6 +22,7 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor
private sealed class ReadItemQueryingEnumerable : IEnumerable, IAsyncEnumerable, IQueryingEnumerable
{
private readonly CosmosQueryContext _cosmosQueryContext;
+ private readonly string _cosmosContainer;
private readonly ReadItemExpression _readItemExpression;
private readonly Func _shaper;
private readonly Type _contextType;
@@ -31,6 +32,7 @@ private sealed class ReadItemQueryingEnumerable : IEnumerable, IAsyncEnume
public ReadItemQueryingEnumerable(
CosmosQueryContext cosmosQueryContext,
+ string cosmosContainer,
ReadItemExpression readItemExpression,
Func shaper,
Type contextType,
@@ -38,6 +40,7 @@ public ReadItemQueryingEnumerable(
bool threadSafetyChecksEnabled)
{
_cosmosQueryContext = cosmosQueryContext;
+ _cosmosContainer = cosmosContainer;
_readItemExpression = readItemExpression;
_shaper = shaper;
_contextType = contextType;
@@ -169,7 +172,7 @@ private bool TryGenerateIdFromKeys(IProperty idProperty, out object value)
private sealed class Enumerator : IEnumerator, IAsyncEnumerator
{
private readonly CosmosQueryContext _cosmosQueryContext;
- private readonly ReadItemExpression _readItemExpression;
+ private readonly string _cosmosContainer;
private readonly Func _shaper;
private readonly Type _contextType;
private readonly IDiagnosticsLogger _queryLogger;
@@ -185,7 +188,7 @@ private sealed class Enumerator : IEnumerator, IAsyncEnumerator
public Enumerator(ReadItemQueryingEnumerable readItemEnumerable, CancellationToken cancellationToken = default)
{
_cosmosQueryContext = readItemEnumerable._cosmosQueryContext;
- _readItemExpression = readItemEnumerable._readItemExpression;
+ _cosmosContainer = readItemEnumerable._cosmosContainer;
_shaper = readItemEnumerable._shaper;
_contextType = readItemEnumerable._contextType;
_queryLogger = readItemEnumerable._queryLogger;
@@ -227,7 +230,7 @@ public bool MoveNext()
EntityFrameworkEventSource.Log.QueryExecuting();
_item = _cosmosQueryContext.CosmosClient.ExecuteReadItem(
- _readItemExpression.Container,
+ _cosmosContainer,
partitionKeyValue,
resourceId);
@@ -279,7 +282,7 @@ public async ValueTask MoveNextAsync()
EntityFrameworkEventSource.Log.QueryExecuting();
_item = await _cosmosQueryContext.CosmosClient.ExecuteReadItemAsync(
- _readItemExpression.Container,
+ _cosmosContainer,
partitionKeyValue,
resourceId,
_cancellationToken)
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
index 3acf05dc059..93634431db9 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
@@ -35,6 +35,11 @@ public partial class CosmosShapedQueryCompilingExpressionVisitor(
///
protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
{
+ if (cosmosQueryCompilationContext.CosmosContainer is null)
+ {
+ throw new UnreachableException("No Cosmos container was set during query processing.");
+ }
+
var jObjectParameter = Parameter(typeof(JObject), "jObject");
var shaperBody = shapedQueryExpression.ShaperExpression;
@@ -64,6 +69,7 @@ protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQuery
Constant(selectExpression),
Constant(shaperLambda.Compile()),
Constant(_contextType),
+ Constant(cosmosQueryCompilationContext.CosmosContainer),
Constant(_partitionKeyValueFromExtension, typeof(PartitionKey)),
Constant(
QueryCompilationContext.QueryTrackingBehavior == QueryTrackingBehavior.NoTrackingWithIdentityResolution),
@@ -85,6 +91,7 @@ protected override Expression VisitShapedQuery(ShapedQueryExpression shapedQuery
Convert(
QueryCompilationContext.QueryContextParameter,
typeof(CosmosQueryContext)),
+ Constant(cosmosQueryCompilationContext.CosmosContainer),
Constant(readItemExpression),
Constant(shaperReadItemLambda.Compile()),
Constant(_contextType),
diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemExpression.cs
index 7b77dd70e89..1989781ce1f 100644
--- a/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemExpression.cs
+++ b/src/EFCore.Cosmos/Query/Internal/Expressions/ReadItemExpression.cs
@@ -32,14 +32,6 @@ public override Type Type
public override ExpressionType NodeType
=> ExpressionType.Extension;
- ///
- /// 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 virtual string Container { get; }
-
///
/// 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
@@ -74,9 +66,6 @@ public ReadItemExpression(
IEntityType entityType,
IDictionary propertyParameters)
{
- Container = entityType.GetContainer()
- ?? throw new UnreachableException("No container ID, or trying to perform ReadItem on owned entity type");
-
ProjectionExpression = new ProjectionExpression(
new EntityProjectionExpression(
entityType,
diff --git a/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs b/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs
index 1ab23bb3917..3f759ce9cc9 100644
--- a/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs
+++ b/src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs
@@ -33,9 +33,6 @@ public class SelectExpression : Expression, IPrintableExpression
///
public SelectExpression(IEntityType entityType)
{
- // TODO: All queries should reference a non-null container ID, but GetContainer returns null for owned entities.
- Container = entityType.GetContainer()!;
-
// TODO: Redo aliasing
_sources = [new SourceExpression(new ObjectReferenceExpression(entityType, "root"), RootAlias)];
_projectionMapping[new ProjectionMember()]
@@ -50,8 +47,6 @@ _projectionMapping[new ProjectionMember()]
///
public SelectExpression(IEntityType entityType, string sql, Expression argument)
{
- // TODO: All queries should reference a non-null container ID, but GetContainer returns null for owned entities.
- Container = entityType.GetContainer()!;
var fromSql = new FromSqlExpression(entityType.ClrType, sql, argument);
_sources = [new SourceExpression(fromSql, RootAlias)];
_projectionMapping[new ProjectionMember()] = new EntityProjectionExpression(
@@ -67,13 +62,11 @@ public SelectExpression(IEntityType entityType, string sql, Expression argument)
public SelectExpression(
List projections,
List sources,
- List orderings,
- string container)
+ List orderings)
{
_projection = projections;
_sources = sources;
_orderings = orderings;
- Container = container;
}
///
@@ -82,20 +75,11 @@ public SelectExpression(
/// 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 SelectExpression(string container, SqlExpression projection)
- : this(container)
+ public SelectExpression(SqlExpression projection)
=> _projectionMapping[new ProjectionMember()] = projection;
- ///
- /// 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 SelectExpression(string? container)
+ private SelectExpression()
{
- // TODO: Move container out of SelectExpression to QueryCompilationContext
- Container = container!;
}
///
@@ -108,7 +92,7 @@ public static SelectExpression CreateForPrimitiveCollection(
SourceExpression source,
Type elementClrType,
CoreTypeMapping elementTypeMapping)
- => new(container: null)
+ => new()
{
_sources = { source },
_projectionMapping =
@@ -118,14 +102,6 @@ public static SelectExpression CreateForPrimitiveCollection(
UsesSingleValueProjection = true
};
- ///
- /// 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 virtual string Container { get; }
-
///
/// 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
@@ -568,7 +544,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor)
if (changed)
{
- var newSelectExpression = new SelectExpression(projections, sources, orderings, Container)
+ var newSelectExpression = new SelectExpression(projections, sources, orderings)
{
_projectionMapping = projectionMapping,
Predicate = predicate,
@@ -603,7 +579,7 @@ public virtual SelectExpression Update(
projectionMapping[projectionMember] = expression;
}
- return new SelectExpression(projections, sources, orderings, Container)
+ return new SelectExpression(projections, sources, orderings)
{
_projectionMapping = projectionMapping,
Predicate = predicate,