diff --git a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
index 39e156405a3..d09996dc4d5 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
@@ -20,7 +21,27 @@ public static class CosmosPropertyExtensions
/// The property name used when targeting Cosmos.
public static string GetCosmosPropertyName([NotNull] this IProperty property) =>
(string)property[CosmosAnnotationNames.PropertyName]
- ?? property.Name;
+ ?? GetDefaultPropertyName(property);
+
+ private static string GetDefaultPropertyName(IProperty property)
+ {
+ var entityType = property.DeclaringEntityType;
+ var ownership = entityType.FindOwnership();
+
+ if (ownership != null
+ && !entityType.IsDocumentRoot())
+ {
+ var pk = property.FindContainingPrimaryKey();
+ if (pk != null
+ && pk.Properties.Count == ownership.Properties.Count + (ownership.IsUnique ? 0 : 1)
+ && ownership.Properties.All(fkProperty => pk.Properties.Contains(fkProperty)))
+ {
+ return "";
+ }
+ }
+
+ return property.Name;
+ }
///
/// Sets the property name used when targeting Cosmos.
diff --git a/src/EFCore.Cosmos/Extensions/CosmosServiceCollectionExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosServiceCollectionExtensions.cs
index b2cdd34dbd9..1b84cc4827b 100644
--- a/src/EFCore.Cosmos/Extensions/CosmosServiceCollectionExtensions.cs
+++ b/src/EFCore.Cosmos/Extensions/CosmosServiceCollectionExtensions.cs
@@ -9,12 +9,14 @@
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal;
using Microsoft.EntityFrameworkCore.Cosmos.Query.Internal;
using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
+using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.EntityFrameworkCore.ValueGeneration;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
@@ -53,6 +55,7 @@ public static IServiceCollection AddEntityFrameworkCosmos([NotNull] this IServic
.TryAdd()
.TryAdd()
.TryAdd()
+ .TryAdd()
.TryAdd()
.TryAdd()
.TryAdd()
diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
index 45bf36ab143..1faff545265 100644
--- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
+++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -187,18 +188,19 @@ private static readonly MethodInfo _getItemMethodInfo
private static readonly MethodInfo _toObjectMethodInfo
= typeof(CosmosProjectionBindingRemovingExpressionVisitor).GetTypeInfo().GetRuntimeMethods()
.Single(mi => mi.Name == nameof(SafeToObject));
- private static readonly MethodInfo _isNullMethodInfo
- = typeof(CosmosProjectionBindingRemovingExpressionVisitor).GetTypeInfo().GetRuntimeMethods()
- .Single(mi => mi.Name == nameof(IsNull));
private readonly SelectExpression _selectExpression;
private readonly ParameterExpression _jObjectParameter;
private readonly bool _trackQueryResults;
- private readonly IDictionary _materializationContextBindings
- = new Dictionary();
+ private readonly IDictionary _materializationContextBindings
+ = new Dictionary();
private readonly IDictionary _projectionBindings
= new Dictionary();
+ private readonly IDictionary _ownerMappings
+ = new Dictionary();
+ private (IEntityType EntityType, ParameterExpression JObjectVariable) _ownerInfo;
+ private ParameterExpression _ordinalParameter;
public CosmosProjectionBindingRemovingExpressionVisitor(
SelectExpression selectExpression,
@@ -231,32 +233,40 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
projectionExpression = ((UnaryExpression)convertExpression.Operand).Operand;
}
- Expression accessExpression;
+ Expression innerAccessExpression;
if (projectionExpression is ObjectArrayProjectionExpression objectArrayProjectionExpression)
{
- accessExpression = objectArrayProjectionExpression.AccessExpression;
+ innerAccessExpression = objectArrayProjectionExpression.AccessExpression;
_projectionBindings[objectArrayProjectionExpression] = parameterExpression;
storeName ??= objectArrayProjectionExpression.Name;
}
else
{
var entityProjectionExpression = (EntityProjectionExpression)projectionExpression;
- _projectionBindings[entityProjectionExpression.AccessExpression] = parameterExpression;
+ var accessExpression = entityProjectionExpression.AccessExpression;
+ _projectionBindings[accessExpression] = parameterExpression;
storeName ??= entityProjectionExpression.Name;
- switch (entityProjectionExpression.AccessExpression)
+ if (_ownerInfo.EntityType != null)
+ {
+ _ownerMappings[accessExpression] = _ownerInfo;
+ }
+
+ switch (accessExpression)
{
case ObjectAccessExpression innerObjectAccessExpression:
- accessExpression = innerObjectAccessExpression.AccessExpression;
+ innerAccessExpression = innerObjectAccessExpression.AccessExpression;
break;
case RootReferenceExpression _:
- accessExpression = _jObjectParameter;
+ innerAccessExpression = _jObjectParameter;
break;
default:
throw new InvalidOperationException();
}
}
- var valueExpression = CreateGetStoreValueExpression(accessExpression, storeName, parameterExpression.Type);
+ var valueExpression = CreateGetValueExpression(innerAccessExpression, storeName, parameterExpression.Type);
+
+ valueExpression = InjectDebug(valueExpression, Expression.Constant(new ExpressionPrinter().Print(innerAccessExpression)), Expression.Constant(storeName));
return Expression.MakeBinary(ExpressionType.Assign, binaryExpression.Left, valueExpression);
}
@@ -277,8 +287,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
entityProjectionExpression = (EntityProjectionExpression)projection;
}
- _materializationContextBindings[parameterExpression]
- = _projectionBindings[entityProjectionExpression.AccessExpression];
+ _materializationContextBindings[parameterExpression] = entityProjectionExpression.AccessExpression;
var updatedExpression = Expression.New(newExpression.Constructor,
Expression.Constant(ValueBuffer.Empty),
@@ -327,7 +336,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
readExpression = Expression.Convert(readExpression, typeof(object));
}
- return readExpression;
+ return InjectDebug(readExpression, Expression.Constant(new ExpressionPrinter().Print(innerExpression)), Expression.Constant(property));
}
return base.VisitMethodCall(methodCallExpression);
@@ -341,7 +350,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
{
var projection = GetProjection(projectionBindingExpression);
- return CreateGetStoreValueExpression(
+ return CreateGetValueExpression(
_jObjectParameter,
projection.Alias,
projectionBindingExpression.Type, (projection.Expression as SqlExpression)?.TypeMapping);
@@ -364,12 +373,20 @@ protected override Expression VisitExtension(Expression extensionExpression)
}
var jArray = _projectionBindings[objectArrayProjection];
- var jObjectParameter = Expression.Parameter(typeof(JObject), jArray.Name + "object");
- var ordinalParameter = Expression.Parameter(typeof(int), "ordinal");
+ var jObjectParameter = Expression.Parameter(typeof(JObject), jArray.Name + "Object");
+ var ordinalParameter = Expression.Parameter(typeof(int), jArray.Name + "Ordinal");
_projectionBindings[objectArrayProjection.InnerProjection.AccessExpression] = jObjectParameter;
+ if (_ownerInfo.EntityType != null)
+ {
+ _ownerMappings[objectArrayProjection.InnerProjection.AccessExpression] = _ownerInfo;
+ }
+ var previousOrdinalParameter = _ordinalParameter;
+ _ordinalParameter = ordinalParameter;
var innerShaper = Visit(collectionShaperExpression.InnerShaper);
+ _ordinalParameter = previousOrdinalParameter;
+
return Expression.Call(
_selectMethodInfo.MakeGenericMethod(typeof(JObject), innerShaper.Type),
Expression.Call(
@@ -389,6 +406,7 @@ protected override Expression VisitExtension(Expression extensionExpression)
// These are the expressions added by JObjectInjectingExpressionVisitor
var jObjectBlock = (BlockExpression)Visit(includeExpression.EntityExpression);
+ var jObjectVariable = jObjectBlock.Variables.Single(v => v.Type == typeof(JObject));
var jObjectCondition = (ConditionalExpression)jObjectBlock.Expressions[jObjectBlock.Expressions.Count - 1];
var shaperBlock = (BlockExpression)jObjectCondition.IfFalse;
@@ -407,7 +425,11 @@ protected override Expression VisitExtension(Expression extensionExpression)
var fixup = GenerateFixup(
includingClrType, relatedEntityClrType, navigation, inverseNavigation)
.Compile();
+
+ var previousOwner = _ownerInfo;
+ _ownerInfo = (navigation.DeclaringEntityType, jObjectVariable);
var navigationExpression = Visit(includeExpression.NavigationExpression);
+ _ownerInfo = previousOwner;
shaperExpressions.Add(Expression.Call(
includeMethod.MakeGenericMethod(includingClrType, relatedEntityClrType),
@@ -601,13 +623,53 @@ private Expression CreateGetValueExpression(
var storeName = property.GetCosmosPropertyName();
if (storeName.Length == 0)
{
+ var entityType = property.DeclaringEntityType;
+ if (!entityType.IsDocumentRoot())
+ {
+ var ownership = entityType.FindOwnership();
+
+ if (ownership != null
+ && !ownership.IsUnique
+ && property.IsPrimaryKey()
+ && !property.IsForeignKey()
+ && property.ClrType == typeof(int))
+ {
+ return _ordinalParameter;
+ }
+
+ var principalProperty = property.FindFirstPrincipal();
+ if (principalProperty != null)
+ {
+ Expression ownerJObjectExpression = null;
+ if (_ownerMappings.TryGetValue(jObjectExpression, out var ownerInfo))
+ {
+ Debug.Assert(principalProperty.DeclaringEntityType.IsAssignableFrom(ownerInfo.EntityType));
+
+ ownerJObjectExpression = ownerInfo.JObjectVariable;
+ }
+ else if (jObjectExpression is RootReferenceExpression rootReferenceExpression)
+ {
+ ownerJObjectExpression = rootReferenceExpression;
+ }
+ else if (jObjectExpression is ObjectAccessExpression objectAccessExpression)
+ {
+ ownerJObjectExpression = objectAccessExpression.AccessExpression;
+ }
+
+ if (ownerJObjectExpression != null)
+ {
+ return CreateGetValueExpression(ownerJObjectExpression, principalProperty);
+ }
+ }
+ }
+
return Expression.Default(property.ClrType);
}
- return CreateGetStoreValueExpression(jObjectExpression, storeName, property.ClrType, property.GetTypeMapping());
+ return CreateGetValueExpression(jObjectExpression, storeName, property.ClrType, property.GetTypeMapping());
}
- private Expression CreateGetStoreValueExpression(
+ private Expression CreateGetValueExpression(
Expression jObjectExpression,
string storeName,
Type clrType,
@@ -620,20 +682,20 @@ private Expression CreateGetStoreValueExpression(
}
else if (jObjectExpression is RootReferenceExpression rootReferenceExpression)
{
- innerExpression = CreateGetStoreValueExpression(
+ innerExpression = CreateGetValueExpression(
_jObjectParameter, rootReferenceExpression.Alias, typeof(JObject));
}
else if (jObjectExpression is ObjectAccessExpression objectAccessExpression)
{
var innerAccessExpression = objectAccessExpression.AccessExpression;
- innerExpression = CreateGetStoreValueExpression(
+ innerExpression = CreateGetValueExpression(
innerAccessExpression, ((IAccessExpression)innerAccessExpression).Name, typeof(JObject));
}
- var jTokenExpression = Expression.Call(innerExpression, _getItemMethodInfo, Expression.Constant(storeName));
- Expression valueExpression;
+ var jTokenExpression = CreateReadJTokenExpression(innerExpression, storeName);
+ Expression valueExpression;
var converter = typeMapping?.Converter;
if (converter != null)
{
@@ -654,15 +716,6 @@ private Expression CreateGetStoreValueExpression(
valueExpression = ConvertJTokenToType(jTokenExpression, clrType);
}
- if (clrType.IsNullableType())
- {
- valueExpression =
- Expression.Condition(
- Expression.Call(_isNullMethodInfo, jTokenExpression),
- Expression.Default(valueExpression.Type),
- valueExpression);
- }
-
return valueExpression;
}
@@ -674,10 +727,24 @@ private static Expression ConvertJTokenToType(Expression jTokenExpression, Type
jTokenExpression);
private static T SafeToObject(JToken token)
- => token == null ? default : token.ToObject();
+ => token == null || token.Type == JTokenType.Null ? default : token.ToObject();
+
+ private static readonly MethodInfo _debugMethodInfo
+ = typeof(CosmosProjectionBindingRemovingExpressionVisitor).GetTypeInfo().GetRuntimeMethods()
+ .Single(mi => mi.Name == nameof(BreakPoint));
+
+ private static Expression InjectDebug(Expression expression, params Expression[] state)
+ => Expression.Call(
+ _debugMethodInfo.MakeGenericMethod(expression.Type),
+ expression,
+ Expression.NewArrayInit(typeof(object),
+ state.Select(s => Expression.Convert(s, typeof(object)))));
- private static bool IsNull(JToken token)
- => token == null || token.Type == JTokenType.Null;
+ private static T BreakPoint(T result, params object[] state)
+ {
+ Debugger.Break();
+ return result;
+ }
}
private class QueryingEnumerable : IEnumerable
diff --git a/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs b/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs
index 6bb460e498a..e58db566b6e 100644
--- a/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs
+++ b/src/EFCore.Cosmos/Query/Internal/ObjectAccessExpression.cs
@@ -35,6 +35,14 @@ public ObjectAccessExpression(INavigation navigation, Expression accessExpressio
AccessExpression = accessExpression;
}
+ ///
+ /// 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 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
diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs
index de846e0801b..8e4af21f01d 100644
--- a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs
+++ b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseCreator.cs
@@ -4,6 +4,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
@@ -55,7 +56,7 @@ public virtual bool EnsureCreated()
{
created |= _cosmosClient.CreateContainerIfNotExists(
entityType.GetCosmosContainer(),
- entityType.GetCosmosPartitionKeyStoreName());
+ GetCosmosPartitionKeyStoreName(entityType));
}
if (created)
@@ -89,7 +90,7 @@ public virtual async Task EnsureCreatedAsync(CancellationToken cancellatio
{
created |= await _cosmosClient.CreateContainerIfNotExistsAsync(
entityType.GetCosmosContainer(),
- entityType.GetCosmosPartitionKeyStoreName(),
+ GetCosmosPartitionKeyStoreName(entityType),
cancellationToken);
}
@@ -145,5 +146,21 @@ public virtual bool CanConnect()
///
public virtual Task CanConnectAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
+
+ ///
+ /// Returns the store name of the property that is used to store the partition key.
+ ///
+ /// The entity type to get the partition key property name for.
+ /// The name of the partition key property.
+ private static string GetCosmosPartitionKeyStoreName([NotNull] IEntityType entityType)
+ {
+ var name = entityType.GetCosmosPartitionKeyPropertyName();
+ if (name != null)
+ {
+ return entityType.FindProperty(name).GetCosmosPropertyName();
+ }
+
+ return CosmosClientWrapper.DefaultPartitionKey;
+ }
}
}
diff --git a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs
index 8ce1803bb31..ede3c39212a 100644
--- a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs
+++ b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs
@@ -71,6 +71,10 @@ public virtual JObject CreateDocument(IUpdateEntry entry)
{
document[storeName] = ConvertPropertyValue(property, entry.GetCurrentValue(property));
}
+ else if (entry.HasTemporaryValue(property))
+ {
+ ((InternalEntityEntry)entry)[property] = entry.GetCurrentValue(property);
+ }
}
foreach (var ownedNavigation in entry.EntityType.GetNavigations())
@@ -130,6 +134,10 @@ public virtual JObject UpdateDocument(JObject document, IUpdateEntry entry)
document[storeName] = ConvertPropertyValue(property, entry.GetCurrentValue(property));
anyPropertyUpdated = true;
}
+ else if (entry.HasTemporaryValue(property))
+ {
+ ((InternalEntityEntry)entry)[property] = entry.GetCurrentValue(property);
+ }
}
}
diff --git a/src/EFCore.Cosmos/ValueGeneration/Internal/CosmosValueGeneratorSelector.cs b/src/EFCore.Cosmos/ValueGeneration/Internal/CosmosValueGeneratorSelector.cs
new file mode 100644
index 00000000000..fdef196d1c0
--- /dev/null
+++ b/src/EFCore.Cosmos/ValueGeneration/Internal/CosmosValueGeneratorSelector.cs
@@ -0,0 +1,31 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.ValueGeneration;
+using Microsoft.EntityFrameworkCore.ValueGeneration.Internal;
+
+namespace Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal
+{
+ public class CosmosValueGeneratorSelector : ValueGeneratorSelector
+ {
+ public CosmosValueGeneratorSelector(ValueGeneratorSelectorDependencies dependencies)
+ : base(dependencies)
+ {
+ }
+
+ public override ValueGenerator Create(IProperty property, IEntityType entityType)
+ {
+ var type = property.ClrType.UnwrapNullableType().UnwrapEnumType();
+
+ if (property.GetCosmosPropertyName() == ""
+ && type == typeof(int))
+ {
+ return new TemporaryIntValueGenerator();
+ }
+
+ return base.Create(property, entityType);
+ }
+ }
+}
diff --git a/src/EFCore.Cosmos/ValueGeneration/Internal/IdValueGenerator.cs b/src/EFCore.Cosmos/ValueGeneration/Internal/IdValueGenerator.cs
index 68fe75bc8de..b0c3d7cc17d 100644
--- a/src/EFCore.Cosmos/ValueGeneration/Internal/IdValueGenerator.cs
+++ b/src/EFCore.Cosmos/ValueGeneration/Internal/IdValueGenerator.cs
@@ -4,7 +4,6 @@
using System.Collections;
using System.Linq;
using System.Text;
-using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal;
using Microsoft.EntityFrameworkCore.ValueGeneration;
diff --git a/src/EFCore.Relational/Query/Internal/FromSqlParameterApplyingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/FromSqlParameterApplyingExpressionVisitor.cs
index 2a651205d30..9fa72e0f1df 100644
--- a/src/EFCore.Relational/Query/Internal/FromSqlParameterApplyingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/FromSqlParameterApplyingExpressionVisitor.cs
@@ -19,16 +19,16 @@ private class FromSqlParameterApplyingExpressionVisitor : ExpressionVisitor
private readonly IDictionary _visitedFromSqlExpressions
= new Dictionary(ReferenceEqualityComparer.Instance);
- private readonly ISqlExpressionFactory _SqlExpressionFactory;
+ private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly ParameterNameGenerator _parameterNameGenerator;
private readonly IReadOnlyDictionary _parametersValues;
public FromSqlParameterApplyingExpressionVisitor(
- ISqlExpressionFactory _sqlExpressionFactory,
+ ISqlExpressionFactory sqlExpressionFactory,
ParameterNameGenerator parameterNameGenerator,
IReadOnlyDictionary parametersValues)
{
- _SqlExpressionFactory = _sqlExpressionFactory;
+ _sqlExpressionFactory = sqlExpressionFactory;
_parameterNameGenerator = parameterNameGenerator;
_parametersValues = parametersValues;
}
@@ -67,7 +67,7 @@ public override Expression Visit(Expression expression)
new TypeMappedRelationalParameter(
parameterName,
parameterName,
- _SqlExpressionFactory.GetTypeMappingForValue(parameterValues[i]),
+ _sqlExpressionFactory.GetTypeMappingForValue(parameterValues[i]),
parameterValues[i]?.GetType().IsNullableType()));
}
}
diff --git a/src/EFCore.Relational/Query/Internal/ParameterValueBasedSelectExpressionOptimizer.cs b/src/EFCore.Relational/Query/Internal/ParameterValueBasedSelectExpressionOptimizer.cs
index c734ffce4d5..c76120f07bd 100644
--- a/src/EFCore.Relational/Query/Internal/ParameterValueBasedSelectExpressionOptimizer.cs
+++ b/src/EFCore.Relational/Query/Internal/ParameterValueBasedSelectExpressionOptimizer.cs
@@ -32,7 +32,6 @@ public SelectExpression Optimize(SelectExpression selectExpression, IReadOnlyDic
_parameterNameGeneratorFactory.Create(),
parametersValues).Visit(query);
-
return (SelectExpression)query;
}
}
diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
index f9b214adcd3..e4fa084e736 100644
--- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
@@ -5,6 +5,7 @@
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;
@@ -86,7 +87,7 @@ public virtual SqlExpression TranslateAverage(Expression expression)
return inputType == typeof(float)
? _sqlExpressionFactory.Convert(
_sqlExpressionFactory.Function(
- "AVG", new[] { sqlExpression }, typeof(double), null),
+ "AVG", new[] { sqlExpression }, typeof(double)),
sqlExpression.Type,
sqlExpression.TypeMapping)
: (SqlExpression)_sqlExpressionFactory.Function(
diff --git a/src/EFCore/Query/NavigationExpansion/Internal/NavigationExpansionHelpers.cs b/src/EFCore/Query/NavigationExpansion/Internal/NavigationExpansionHelpers.cs
index e5e3ee3c91e..634652c860f 100644
--- a/src/EFCore/Query/NavigationExpansion/Internal/NavigationExpansionHelpers.cs
+++ b/src/EFCore/Query/NavigationExpansion/Internal/NavigationExpansionHelpers.cs
@@ -234,10 +234,7 @@ public static Expression CreateKeyAccessExpression(
AnonymousObject.AnonymousObjectCtor,
Expression.NewArrayInit(
typeof(object),
- properties
- .Select(p => Expression.Convert(CreatePropertyExpression(target, p, addNullCheck), typeof(object)))
- .Cast()
- .ToArray()));
+ properties.Select(p => Expression.Convert(CreatePropertyExpression(target, p, addNullCheck), typeof(object)))));
private static Expression CreatePropertyExpression(Expression target, IProperty property, bool addNullCheck)
{
diff --git a/test/EFCore.Cosmos.FunctionalTests/NestedDocumentsTest.cs b/test/EFCore.Cosmos.FunctionalTests/NestedDocumentsTest.cs
index 264ea9982d0..3405be050ae 100644
--- a/test/EFCore.Cosmos.FunctionalTests/NestedDocumentsTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/NestedDocumentsTest.cs
@@ -80,8 +80,7 @@ public virtual async Task Can_update_owner_with_dependents()
}
}
- // #12086
- //[ConditionalFact]
+ [ConditionalFact]
public virtual async Task Can_add_collection_dependent_to_owner()
{
await using (var testDatabase = CreateTestStore())
@@ -158,9 +157,8 @@ public virtual async Task Can_add_collection_dependent_to_owner()
var json = context.Entry(people[1]).Property("__jObject").CurrentValue;
var jsonAddress = (JObject)((JArray)json["Stored Addresses"])[0];
Assert.Equal("Second", jsonAddress[nameof(Address.Street)]);
- // Uncomment when issue #13578 is fixed
- //Assert.Equal(2, jsonAddress["unmappedId"]);
- //Assert.Equal(2, jsonAddress.Count);
+ Assert.Equal(2, jsonAddress["unmappedId"]);
+ Assert.Equal(2, jsonAddress.Count);
addresses = people[2].Addresses.ToList();
Assert.Equal(3, addresses.Count);
@@ -192,8 +190,7 @@ public virtual async Task Can_query_just_nested_reference()
}
}
- // #12086
- //[ConditionalFact]
+ [ConditionalFact]
public virtual async Task Can_query_just_nested_collection()
{
await using (var testDatabase = CreateTestStore())
diff --git a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs
index 03847fdb35c..f459f300d04 100644
--- a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs
@@ -11,7 +11,6 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.TestUtilities;
-using Microsoft.EntityFrameworkCore.TestUtilities.Xunit;
using Xunit;
using Xunit.Abstractions;