diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs index ae23dd0bc77..229f836e715 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs @@ -55,7 +55,7 @@ public static string IdNonStringStoreType([CanBeNull] object idProperty, [CanBeN idProperty, entityType, propertyType); /// - /// 'UpdateEntityType' called with '{derivedType}' which is not derived type of '{entityType}'. + /// The specified entity type '{derivedType}' is not derived from '{entityType}'. /// public static string InvalidDerivedTypeInEntityProjection([CanBeNull] object derivedType, [CanBeNull] object entityType) => string.Format( @@ -63,7 +63,7 @@ public static string InvalidDerivedTypeInEntityProjection([CanBeNull] object der derivedType, entityType); /// - /// Invalid 'id' value. Supply a string value that's not null or empty. + /// Unable to generate a valid 'id' value to execute ReadItem query. This usually happens when value provided for one of the properties is null or empty string. Please supply a value that's not null or empty. /// public static string InvalidResourceId => GetString("InvalidResourceId"); @@ -77,10 +77,10 @@ public static string JsonPropertyCollision([CanBeNull] object property1, [CanBeN property1, property2, entityType, storeName); /// - /// Reverse could not be translated to the server because there is no ordering on the server side. + /// 'Reverse' could not be translated to the server because there is no ordering on the server side. /// - public static string MissingOrderingInSqlExpression - => GetString("MissingOrderingInSqlExpression"); + public static string MissingOrderingInSelectExpression + => GetString("MissingOrderingInSelectExpression"); /// /// Navigation '{entityType}.{navigationName}' doesn't point to an embedded entity. @@ -123,12 +123,12 @@ public static string NoIdProperty([CanBeNull] object entityType) entityType); /// - /// Non-embedded IncludeExpression is not supported: {expression} + /// Including navigation '{navigation}' is not supported as the navigation is not embedded in same resource. /// - public static string NonEmbeddedIncludeNotSupported([CanBeNull] object expression) + public static string NonEmbeddedIncludeNotSupported([CanBeNull] object navigation) => string.Format( - GetString("NonEmbeddedIncludeNotSupported", nameof(expression)), - expression); + GetString("NonEmbeddedIncludeNotSupported", nameof(navigation)), + navigation); /// /// The entity type '{entityType}' has property '{property}' as its concurrency token, but only '_etag' is supported. Consider using 'EntityTypeBuilder.UseETagConcurrency'. @@ -171,7 +171,7 @@ public static string NullTypeMappingInSqlTree([CanBeNull] object sqlExpression) sqlExpression); /// - /// Offset is not supported without Limit. + /// Cosmos SQL does not allow Offset without Limit. Consider specifying 'Take' operation on the query. /// public static string OffsetRequiresLimit => GetString("OffsetRequiresLimit"); @@ -193,7 +193,7 @@ public static string OrphanedNestedDocumentSensitive([CanBeNull] object entityTy entityType, missingEntityType, keyValue); /// - /// A ReadItem query was detected, but the partition key value is missing. + /// Unable to execute a ReadItem query since the partition key value is missing. Consider using 'WithPartitionKey' method on the query to specify partition key to use. /// public static string ParitionKeyMissing => GetString("ParitionKeyMissing"); @@ -231,16 +231,16 @@ public static string PartitionKeyStoreNameMismatch([CanBeNull] object property1, property1, entityType1, storeName1, property2, entityType2, storeName2); /// - /// A ReadItem query was detected, but the 'id' value is missing and cannot be generated. + /// Unable to execute a ReadItem query since the 'id' value is missing and cannot be generated. /// public static string ResourceIdMissing => GetString("ResourceIdMissing"); /// - /// Reverse is not supported without Limit or Offset. + /// Reversing the ordering in 'SelectExpression' is not supported when limit or offset are already applied. /// - public static string ReverseRequiresOffsetOrLimit - => GetString("ReverseRequiresOffsetOrLimit"); + public static string ReverseAfterSkipTakeNotSupported + => GetString("ReverseAfterSkipTakeNotSupported"); /// /// Unable to bind '{memberType}' '{member}' to entity projection of '{entityType}'. @@ -267,7 +267,7 @@ public static string UpdateConflict([CanBeNull] object itemId) itemId); /// - /// VisitChildren must be overridden in class deriving from SqlExpression. + /// 'VisitChildren' must be overridden in the class deriving from 'SqlExpression'. /// public static string VisitChildrenMustBeOverridden => GetString("VisitChildrenMustBeOverridden"); diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.resx b/src/EFCore.Cosmos/Properties/CosmosStrings.resx index 285edc4c8c2..83d9834923a 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.resx +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.resx @@ -133,16 +133,16 @@ The type of the '{idProperty}' property on '{entityType}' is '{propertyType}'. All 'id' properties need to be strings or have a string converter. - 'UpdateEntityType' called with '{derivedType}' which is not derived type of '{entityType}'. + The specified entity type '{derivedType}' is not derived from '{entityType}'. - Invalid 'id' value. Supply a string value that's not null or empty. + Unable to generate a valid 'id' value to execute ReadItem query. This usually happens when value provided for one of the properties is null or empty string. Please supply a value that's not null or empty. Both properties '{property1}' and '{property2}' on entity type '{entityType}' are mapped to '{storeName}'. Map one of the properties to a different JSON property. - - Reverse could not be translated to the server because there is no ordering on the server side. + + 'Reverse' could not be translated to the server because there is no ordering on the server side. Navigation '{entityType}.{navigationName}' doesn't point to an embedded entity. @@ -160,7 +160,7 @@ The entity type '{entityType}' does not have a property mapped to the 'id' property in the database. Add a property mapped as 'id'. - Non-embedded IncludeExpression is not supported: {expression} + Including navigation '{navigation}' is not supported as the navigation is not embedded in same resource. The entity type '{entityType}' has property '{property}' as its concurrency token, but only '_etag' is supported. Consider using 'EntityTypeBuilder.UseETagConcurrency'. @@ -178,7 +178,7 @@ Expression '{sqlExpression}' in SQL tree does not have type mapping assigned. - Offset is not supported without Limit. + Cosmos SQL does not allow Offset without Limit. Consider specifying 'Take' operation on the query. The entity of type '{entityType}' is mapped as a part of the document mapped to '{missingEntityType}', but there is no tracked entity of this type with the corresponding key value. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values. @@ -187,7 +187,7 @@ The entity of type '{entityType}' is mapped as a part of the document mapped to '{missingEntityType}', but there is no tracked entity of this type with the key value '{keyValue}'. - A ReadItem query was detected, but the partition key value is missing. + Unable to execute a ReadItem query since the partition key value is missing. Consider using 'WithPartitionKey' method on the query to specify partition key to use. Partition key specified in the WithPartitionKey call '{paritionKey1}' and the partition key specified in the Where predicate '{paritionKey2}' must be identical. Remove one of them . @@ -202,10 +202,10 @@ The partition key property '{property1}' on '{entityType1}' is mapped as '{storeName1}', but the partition key property '{property2}' on '{entityType2}' is mapped as '{storeName2}'. All partition key properties need to be mapped to the same store property. - A ReadItem query was detected, but the 'id' value is missing and cannot be generated. + Unable to execute a ReadItem query since the 'id' value is missing and cannot be generated. - - Reverse is not supported without Limit or Offset. + + Reversing the ordering in 'SelectExpression' is not supported when limit or offset are already applied. Unable to bind '{memberType}' '{member}' to entity projection of '{entityType}'. @@ -217,6 +217,6 @@ Conflicts were detected for item with id '{itemId}'. - VisitChildren must be overridden in class deriving from SqlExpression. + 'VisitChildren' must be overridden in the class deriving from 'SqlExpression'. \ No newline at end of file diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs index 2c9854a2182..e7df8bcec49 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs @@ -255,7 +255,8 @@ protected override Expression VisitExtension(Expression extensionExpression) if (!(includeExpression.Navigation is INavigation includableNavigation && includableNavigation.IsEmbedded())) { - throw new InvalidOperationException(CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Print())); + throw new InvalidOperationException( + CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Navigation)); } _includedNavigations.Push(includableNavigation); diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs index 206f25ce8f6..a5860d137cb 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosQueryableMethodTranslatingExpressionVisitor.cs @@ -821,7 +821,7 @@ protected override ShapedQueryExpression TranslateReverse(ShapedQueryExpression var selectExpression = (SelectExpression)source.QueryExpression; if (selectExpression.Orderings.Count == 0) { - AddTranslationErrorDetails(CosmosStrings.MissingOrderingInSqlExpression); + AddTranslationErrorDetails(CosmosStrings.MissingOrderingInSelectExpression); return null; } diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs index 79d70940519..2d27fee9c71 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.CosmosProjectionBindingRemovingExpressionVisitorBase.cs @@ -215,7 +215,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp || navigation.IsOnDependent || navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot()) { - throw new InvalidOperationException(CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Print())); + throw new InvalidOperationException( + CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Navigation)); } _pendingIncludes.Add(includeExpression); @@ -296,7 +297,8 @@ protected override Expression VisitExtension(Expression extensionExpression) || navigation.IsOnDependent || navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot()) { - throw new InvalidOperationException(CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Print())); + throw new InvalidOperationException( + CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Navigation)); } var isFirstInclude = _pendingIncludes.Count == 0; diff --git a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs index 6ee34818703..ac58f5e2184 100644 --- a/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/EntityProjectionExpression.cs @@ -120,7 +120,7 @@ public virtual Expression BindProperty([NotNull] IProperty property, bool client && !property.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - CosmosStrings.UnableToBindMemberToEntityProjection("Property", property.Name, EntityType.DisplayName())); + CosmosStrings.UnableToBindMemberToEntityProjection("property", property.Name, EntityType.DisplayName())); } if (!_propertyExpressionsMap.TryGetValue(property, out var expression)) @@ -130,7 +130,7 @@ public virtual Expression BindProperty([NotNull] IProperty property, bool client } if (!clientEval - // TODO: Remove once __jObject is translated to the access root in a better fashion and + // TODO: Remove once __jObject is translated to the access root in a better fashion and // would not otherwise be found to be non-translatable. See issues #17670 and #14121. && property.Name != StoreKeyConvention.JObjectPropertyName && expression.Name.Length == 0) @@ -154,7 +154,7 @@ public virtual Expression BindNavigation([NotNull] INavigation navigation, bool && !navigation.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - CosmosStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName())); + CosmosStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } if (!_navigationExpressionsMap.TryGetValue(navigation, out var expression)) diff --git a/src/EFCore.Cosmos/Query/Internal/SelectExpression.cs b/src/EFCore.Cosmos/Query/Internal/SelectExpression.cs index cae99b0795c..d0faf8783cd 100644 --- a/src/EFCore.Cosmos/Query/Internal/SelectExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/SelectExpression.cs @@ -399,7 +399,7 @@ public virtual void ReverseOrderings() if (Limit != null || Offset != null) { - throw new InvalidOperationException(CosmosStrings.ReverseRequiresOffsetOrLimit); + throw new InvalidOperationException(CosmosStrings.ReverseAfterSkipTakeNotSupported); } var existingOrderings = _orderings.ToArray(); diff --git a/src/EFCore.InMemory/Properties/InMemoryStrings.Designer.cs b/src/EFCore.InMemory/Properties/InMemoryStrings.Designer.cs index 4955c5f272a..423a6baa321 100644 --- a/src/EFCore.InMemory/Properties/InMemoryStrings.Designer.cs +++ b/src/EFCore.InMemory/Properties/InMemoryStrings.Designer.cs @@ -22,27 +22,19 @@ private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.EntityFrameworkCore.InMemory.Properties.InMemoryStrings", typeof(InMemoryStrings).Assembly); /// - /// Cannot apply DefaultIfEmpty after a client-evaluated projection. + /// Cannot apply 'DefaultIfEmpty' after a client-evaluated projection. Consider applying 'DefaultIfEmpty' before last 'Select' or use 'AsEnumerable' before 'DefaultIfEmpty' to apply it on client-side. /// public static string DefaultIfEmptyAppliedAfterProjection => GetString("DefaultIfEmptyAppliedAfterProjection"); /// - /// 'UpdateEntityType' called with '{derivedType}' which is not derived type of '{entityType}'. + /// The specified entity type '{derivedType}' is not derived from '{entityType}'. /// public static string InvalidDerivedTypeInEntityProjection([CanBeNull] object derivedType, [CanBeNull] object entityType) => string.Format( GetString("InvalidDerivedTypeInEntityProjection", nameof(derivedType), nameof(entityType)), derivedType, entityType); - /// - /// Invalid {state} encountered. - /// - public static string InvalidStateEncountered([CanBeNull] object state) - => string.Format( - GetString("InvalidStateEncountered", nameof(state)), - state); - /// /// There is no query string because the in-memory provider does not use a string-based query language. /// diff --git a/src/EFCore.InMemory/Properties/InMemoryStrings.resx b/src/EFCore.InMemory/Properties/InMemoryStrings.resx index 918d4556e5c..3392f32f0a7 100644 --- a/src/EFCore.InMemory/Properties/InMemoryStrings.resx +++ b/src/EFCore.InMemory/Properties/InMemoryStrings.resx @@ -118,13 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Cannot apply DefaultIfEmpty after a client-evaluated projection. + Cannot apply 'DefaultIfEmpty' after a client-evaluated projection. Consider applying 'DefaultIfEmpty' before last 'Select' or use 'AsEnumerable' before 'DefaultIfEmpty' to apply it on client-side. - 'UpdateEntityType' called with '{derivedType}' which is not derived type of '{entityType}'. - - - Invalid {state} encountered. + The specified entity type '{derivedType}' is not derived from '{entityType}'. Saved {count} entities to in-memory store. diff --git a/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs b/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs index aac4e0f8d90..ad230acc93f 100644 --- a/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs +++ b/src/EFCore.InMemory/Query/Internal/EntityProjectionExpression.cs @@ -107,7 +107,7 @@ public virtual Expression BindProperty([NotNull] IProperty property) && !property.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - InMemoryStrings.UnableToBindMemberToEntityProjection("Property", property.Name, EntityType.DisplayName())); + InMemoryStrings.UnableToBindMemberToEntityProjection("property", property.Name, EntityType.DisplayName())); } return _readExpressionMap[property]; @@ -125,7 +125,7 @@ public virtual void AddNavigationBinding([NotNull] INavigation navigation, [NotN && !navigation.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - InMemoryStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName())); + InMemoryStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } _navigationExpressionsCache[navigation] = entityShaper; @@ -143,7 +143,7 @@ public virtual EntityShaperExpression BindNavigation([NotNull] INavigation navig && !navigation.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - InMemoryStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName())); + InMemoryStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } return _navigationExpressionsCache.TryGetValue(navigation, out var expression) diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs index caa220282ec..fb7a2a589c7 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using System.Reflection; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.InMemory.Internal; using Microsoft.EntityFrameworkCore.Metadata; @@ -276,7 +277,7 @@ public override Expression Visit(Expression expression) : mappingValue is int index ? new ProjectionBindingExpression( projectionBindingExpression.QueryExpression, index, projectionBindingExpression.Type) - : throw new InvalidOperationException(InMemoryStrings.InvalidStateEncountered("ProjectionMapping")); + : throw new InvalidOperationException(CoreStrings.UnknownEntity("ProjectionMapping")); } return base.Visit(expression); diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs index 15df3c4dcef..db9df7c7130 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using System.Reflection; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.InMemory.Internal; using Microsoft.EntityFrameworkCore.Metadata; @@ -1498,7 +1499,7 @@ MethodInfo GetMethod() nameof(Enumerable.Max) => EnumerableMethods.GetMaxWithSelector(selector.ReturnType), nameof(Enumerable.Min) => EnumerableMethods.GetMinWithSelector(selector.ReturnType), nameof(Enumerable.Sum) => EnumerableMethods.GetSumWithSelector(selector.ReturnType), - _ => throw new InvalidOperationException(InMemoryStrings.InvalidStateEncountered("Aggregate Operator")), + _ => throw new InvalidOperationException(CoreStrings.UnknownEntity("Aggregate Operator")), }; } diff --git a/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs b/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs index 4bebc0320f3..41b6dfcb3d4 100644 --- a/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs @@ -158,7 +158,7 @@ private static FromSqlQueryRootExpression GenerateFromSqlQueryRoot( if ((entityType.BaseType != null || entityType.GetDirectlyDerivedTypes().Any()) && entityType.GetDiscriminatorProperty() == null) { - throw new InvalidOperationException(RelationalStrings.NonTPHOnFromSqlNotSupported(memberName, entityType.DisplayName())); + throw new InvalidOperationException(RelationalStrings.MethodOnNonTPHRootNotSupported(memberName, entityType.DisplayName())); } return new FromSqlQueryRootExpression( diff --git a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs index 3830a9e8cc2..e4398812c8a 100644 --- a/src/EFCore.Relational/Metadata/Internal/DbFunction.cs +++ b/src/EFCore.Relational/Metadata/Internal/DbFunction.cs @@ -426,7 +426,7 @@ public virtual bool SetIsNullable(bool nullable, ConfigurationSource configurati { if (!IsScalar) { - new InvalidOperationException(RelationalStrings.NullabilityInfoOnlyAllowedOnScalarFunctions); + new InvalidOperationException(RelationalStrings.NonScalarFunctionCannotBeNullable(Name)); } _nullable = nullable; @@ -545,15 +545,9 @@ public virtual Func, SqlExpression> SetTransl ConfigurationSource configurationSource) { if (translation != null - && !IsScalar) + && (!IsScalar || IsAggregate)) { - throw new InvalidOperationException(RelationalStrings.DbFunctionTableValuedCustomTranslation(MethodInfo.DisplayName())); - } - - if (translation != null - && IsAggregate) - { - throw new InvalidOperationException(RelationalStrings.DbFunctionAggregateCustomTranslation(MethodInfo.DisplayName())); + throw new InvalidOperationException(RelationalStrings.DbFunctionNonScalarCustomTranslation(MethodInfo.DisplayName())); } _translation = translation; diff --git a/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs b/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs index 3af162b9679..091b56a586f 100644 --- a/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs +++ b/src/EFCore.Relational/Metadata/Internal/DbFunctionParameter.cs @@ -193,7 +193,7 @@ public virtual bool SetPropagatesNullability(bool propagatesNullability, Configu { if (!Function.IsScalar) { - new InvalidOperationException(RelationalStrings.NullabilityInfoOnlyAllowedOnScalarFunctions); + new InvalidOperationException(RelationalStrings.NonScalarFunctionParameterCannotPropagatesNullability(Name, Function.Name)); } _propagatesNullability = propagatesNullability; diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs index e10fbcf4b8e..2c1515f3fdb 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs +++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs @@ -43,7 +43,7 @@ public static string CannotChangeWhenOpen => GetString("CannotChangeWhenOpen"); /// - /// The given GroupBy pattern is not translatable. Call AsEnumerable before GroupBy to evaluate it locally. + /// Unable to translate the given 'GroupBy' pattern. Call 'AsEnumerable' before 'GroupBy' to evaluate it client-side. /// public static string ClientGroupByNotSupported => GetString("ClientGroupByNotSupported"); @@ -146,14 +146,6 @@ public static string DataOperationNoTable([CanBeNull] object table) GetString("DataOperationNoTable", nameof(table)), table); - /// - /// Cannot set custom translation on the DbFunction '{function}' since it is an aggregate function. - /// - public static string DbFunctionAggregateCustomTranslation([CanBeNull] object function) - => string.Format( - GetString("DbFunctionAggregateCustomTranslation", nameof(function)), - function); - /// /// The provided DbFunction expression '{expression}' is invalid. The expression should be a lambda expression containing a single method call to the target static method. Default values can be provided as arguments if required. E.g. () => SomeClass.SomeMethod(null, 0) /// @@ -163,7 +155,7 @@ public static string DbFunctionExpressionIsNotMethodCall([CanBeNull] object expr expression); /// - /// The DbFunction '{function}' is generic. Generic methods are not supported. + /// The DbFunction '{function}' is generic. Mapping generic methods as a DbFunction is not supported. /// public static string DbFunctionGenericMethodNotSupported([CanBeNull] object function) => string.Format( @@ -187,7 +179,7 @@ public static string DbFunctionInvalidIQueryableOwnedReturnType([CanBeNull] obje function, type); /// - /// The DbFunction '{function}' has an invalid return type '{type}'. Non-scalar functions must return IQueryable of a valid entity type. + /// The DbFunction '{function}' has an invalid return type '{type}'. Non-scalar functions must return 'IQueryable' of a valid entity type. /// public static string DbFunctionInvalidIQueryableReturnType([CanBeNull] object function, [CanBeNull] object type) => string.Format( @@ -211,7 +203,7 @@ public static string DbFunctionInvalidParameterType([CanBeNull] object parameter parameter, function, type); /// - /// The DbFunction '{function}' returns '{type}', but `{elementType}` is not a mapped entity type. Ensure that `{elementType}` is included in the model. + /// The DbFunction '{function}' returns '{type}', but '{elementType}' is not a mapped entity type. Ensure that '{elementType}' is included in the model. /// public static string DbFunctionInvalidReturnEntityType([CanBeNull] object function, [CanBeNull] object type, [CanBeNull] object elementType) => string.Format( @@ -227,11 +219,11 @@ public static string DbFunctionInvalidReturnType([CanBeNull] object function, [C function, type); /// - /// Cannot set custom translation on the DbFunction '{function}' since it is a table valued function. + /// Cannot set custom translation on the DbFunction '{function}' since it is not a scalar function. /// - public static string DbFunctionTableValuedCustomTranslation([CanBeNull] object function) + public static string DbFunctionNonScalarCustomTranslation([CanBeNull] object function) => string.Format( - GetString("DbFunctionTableValuedCustomTranslation", nameof(function)), + GetString("DbFunctionNonScalarCustomTranslation", nameof(function)), function); /// @@ -538,7 +530,7 @@ public static string FromSqlMissingColumn([CanBeNull] object column) column); /// - /// FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it. Consider calling `AsEnumerable` after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side. + /// 'FromSqlRaw' or 'FromSqlInterpolated' was called with non-composable SQL and with a query composing over it. Consider calling 'AsEnumerable' after the method to perform the composition on the client side. /// public static string FromSqlNonComposable => GetString("FromSqlNonComposable"); @@ -551,12 +543,6 @@ public static string FunctionOverrideMismatch([CanBeNull] object propertySpecifi GetString("FunctionOverrideMismatch", nameof(propertySpecification), nameof(function)), propertySpecification, function); - /// - /// Data is null. This method or property cannot be called on null values. - /// - public static string GetXMethodOnNullData - => GetString("GetXMethodOnNullData"); - /// /// Cannot use table '{table}' for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and the comment '{comment}' does not match the comment '{otherComment}'. /// @@ -646,7 +632,7 @@ public static string InsertDataOperationValuesCountMismatch([CanBeNull] object v valuesCount, columnsCount, table); /// - /// Not enough information to uniquely identify outer element in correlated collection scenario. This can happen when trying to correlate on keyless entity or when using 'Distinct' or 'GroupBy' operations without projecting all of the key columns. + /// Unable to translate collection subquery in projection since the parent query doesn't project key columns of all of it's tables which are required to generate results on client side. This can happen when trying to correlate on keyless entity or when using 'Distinct' or 'GroupBy' operations without projecting all of the key columns. /// public static string InsufficientInformationToIdentifyOuterElementOfCollectionJoin => GetString("InsufficientInformationToIdentifyOuterElementOfCollectionJoin"); @@ -666,10 +652,12 @@ public static string InvalidDerivedTypeInEntityProjection([CanBeNull] object der derivedType, entityType); /// - /// Invalid keySelector for GroupBy. + /// The grouping key '{keySelector}' is of type '{keyType}' which is not valid key. /// - public static string InvalidKeySelectorForGroupBy - => GetString("InvalidKeySelectorForGroupBy"); + public static string InvalidKeySelectorForGroupBy([CanBeNull] object keySelector, [CanBeNull] object keyType) + => string.Format( + GetString("InvalidKeySelectorForGroupBy", nameof(keySelector), nameof(keyType)), + keySelector, keyType); /// /// The entity type '{entityType}' is mapped to the DbFunction named '{functionName}' and it's derived from '{baseEntityType}'. Derived entity types cannot be mapped to a function. @@ -716,7 +704,7 @@ public static string InvalidMinBatchSize => GetString("InvalidMinBatchSize"); /// - /// Queries performing '{method}' operation must have a deterministic sort order. Rewrite the query to apply an OrderBy clause on the sequence before calling '{method}'. + /// Queries performing '{method}' operation must have a deterministic sort order. Rewrite the query to apply an 'OrderBy' clause on the sequence before calling '{method}'. /// public static string LastUsedWithoutOrderBy([CanBeNull] object method) => string.Format( @@ -731,6 +719,14 @@ public static string MappedFunctionNotFound([CanBeNull] object entityType, [CanB GetString("MappedFunctionNotFound", nameof(entityType), nameof(functionName)), entityType, functionName); + /// + /// Using '{methodName}' on DbSet of '{entityType}' is not supported since '{entityType}' is part of hierarchy and does not contain a discriminator property. + /// + public static string MethodOnNonTPHRootNotSupported([CanBeNull] object methodName, [CanBeNull] object entityType) + => string.Format( + GetString("MethodOnNonTPHRootNotSupported", nameof(methodName), nameof(entityType)), + methodName, entityType); + /// /// The migration '{migrationName}' was not found. /// @@ -748,7 +744,7 @@ public static string MissingConcurrencyColumn([CanBeNull] object entityType, [Ca entityType, missingColumn, table); /// - /// Collection subquery that uses 'Distinct' or 'Group By' operations must project key columns of all of it's tables. Missing column: {column}. Either add column(s) to the projection or rewrite query to not use 'GroupBy'/'Distinct' operation. + /// Unable to translate collection subquery in projection since it uses 'Distinct' or 'Group By' operations and doesn't project key columns of all of it's tables which are required to generate results on client side. Missing column: {column}. Either add column(s) to the projection or rewrite query to not use 'GroupBy'/'Distinct' operation. /// public static string MissingIdentifyingProjectionInDistinctGroupBySubquery([CanBeNull] object column) => string.Format( @@ -758,8 +754,8 @@ public static string MissingIdentifyingProjectionInDistinctGroupBySubquery([CanB /// /// Reverse could not be translated to the server because there is no ordering on the server side. /// - public static string MissingOrderingInSqlExpression - => GetString("MissingOrderingInSqlExpression"); + public static string MissingOrderingInSelectExpression + => GetString("MissingOrderingInSelectExpression"); /// /// No value provided for required parameter '{parameter}'. @@ -822,12 +818,20 @@ public static string NoneRelationalTypeMappingOnARelationalTypeMappingSource => GetString("NoneRelationalTypeMappingOnARelationalTypeMappingSource"); /// - /// Using '{memberName}' on DbSet of '{entityType}' is not supported since '{entityType}' is part of hierarchy and does not contain a discriminator property. + /// Cannot set 'IsNullable' on DbFunction '{functionName}' since the function does not represent a scalar function. /// - public static string NonTPHOnFromSqlNotSupported([CanBeNull] object memberName, [CanBeNull] object entityType) + public static string NonScalarFunctionCannotBeNullable([CanBeNull] object functionName) => string.Format( - GetString("NonTPHOnFromSqlNotSupported", nameof(memberName), nameof(entityType)), - memberName, entityType); + GetString("NonScalarFunctionCannotBeNullable", nameof(functionName)), + functionName); + + /// + /// Cannot set 'PropagatesNullability' on parameter '{parameterName}' of DbFunction '{functionName}' since function does not represent a scalar function. + /// + public static string NonScalarFunctionParameterCannotPropagatesNullability([CanBeNull] object parameterName, [CanBeNull] object functionName) + => string.Format( + GetString("NonScalarFunctionParameterCannotPropagatesNullability", nameof(parameterName), nameof(functionName)), + parameterName, functionName); /// /// Both '{entityType}' and '{otherEntityType}' are mapped to the table '{table}'. All the entity types in a hierarchy that don't have a discriminator must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information. @@ -851,20 +855,6 @@ public static string NonTPHViewClash([CanBeNull] object entityType, [CanBeNull] public static string NoProviderConfigured => GetString("NoProviderConfigured"); - /// - /// The subquery '{subquery}' references type '{type}' for which no type mapping could be found. - /// - public static string NoTypeMappingFoundForSubquery([CanBeNull] object subquery, [CanBeNull] object type) - => string.Format( - GetString("NoTypeMappingFoundForSubquery", nameof(subquery), nameof(type)), - subquery, type); - - /// - /// Nullability information should only be specified for scalar database functions. - /// - public static string NullabilityInfoOnlyAllowedOnScalarFunctions - => GetString("NullabilityInfoOnlyAllowedOnScalarFunctions"); - /// /// Expression '{sqlExpression}' in SQL tree does not have type mapping assigned. /// @@ -888,7 +878,7 @@ public static string PendingAmbientTransaction => GetString("PendingAmbientTransaction"); /// - /// Different projection mapping count in set operation. + /// Unable to translate set operation when both sides don't assign values to same properties in the nominal type. Please make sure that the properties are inclued on both sides, consider assigning default value if the property doesn't require a specific value. /// public static string ProjectionMappingCountMismatch => GetString("ProjectionMappingCountMismatch"); @@ -901,12 +891,6 @@ public static string PropertyNotMappedToTable([CanBeNull] object property, [CanB GetString("PropertyNotMappedToTable", nameof(property), nameof(entityType), nameof(table)), property, entityType, table); - /// - /// Unable to identify the concrete entity type to materialize in TPT hierarchy. - /// - public static string QueryUnableToIdentifyConcreteTypeInTPT - => GetString("QueryUnableToIdentifyConcreteTypeInTPT"); - /// /// The entity type '{entityType}' is not mapped to a table, therefore the entities cannot be persisted to the database. Use 'ToTable' in 'OnModelCreating' to map it. /// @@ -930,19 +914,13 @@ public static string SelectExpressionNonTPHWithCustomTable([CanBeNull] object en entityType); /// - /// Sequence contains no elements. - /// - public static string SequenceContainsNoElements - => GetString("SequenceContainsNoElements"); - - /// - /// Can't process set operations after client evaluation, consider moving the operation before the last 'Select' call (see issue #16243). + /// Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call. /// public static string SetOperationsNotAllowedAfterClientEvaluation => GetString("SetOperationsNotAllowedAfterClientEvaluation"); /// - /// Set operations over different store types are currently unsupported. + /// Unable to translate set operation when matching columns on both sides have different store types. /// public static string SetOperationsOnDifferentStoreTypes => GetString("SetOperationsOnDifferentStoreTypes"); @@ -1002,10 +980,12 @@ public static string TimeoutTooSmall([CanBeNull] object seconds) seconds); /// - /// The underlying reader doesn't have as many fields as expected. + /// The underlying reader doesn't have as many fields as expected. Expected: {expected}, actual: {actual}. /// - public static string TooFewReaderFields - => GetString("TooFewReaderFields"); + public static string TooFewReaderFields([CanBeNull] object expected, [CanBeNull] object actual) + => string.Format( + GetString("TooFewReaderFields", nameof(expected), nameof(actual)), + expected, actual); /// /// '{entityType}' is mapped to the table '{table}' while '{otherEntityType}' is mapped to the table '{otherTable}'. Map all the entity types in the hierarchy to the same table or remove the discriminator and map all of them to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information. @@ -1052,11 +1032,11 @@ public static string UnableToSplitCollectionProjectionInSplitQuery([CanBeNull] o splitQueryEnumValue, splitQueryMethodName, singleQueryMethodName); /// - /// Unknown expression '{expression}' of type - '{expressionType}' encountered in '{visitor}'. + /// Unhandled expression '{expression}' of type '{expressionType}' encountered in '{visitor}'. /// - public static string UnknownExpressionType([CanBeNull] object expression, [CanBeNull] object expressionType, [CanBeNull] object visitor) + public static string UnhandledExpressionInVisitor([CanBeNull] object expression, [CanBeNull] object expressionType, [CanBeNull] object visitor) => string.Format( - GetString("UnknownExpressionType", nameof(expression), nameof(expressionType), nameof(visitor)), + GetString("UnhandledExpressionInVisitor", nameof(expression), nameof(expressionType), nameof(visitor)), expression, expressionType, visitor); /// @@ -1067,14 +1047,6 @@ public static string UnknownOperation([CanBeNull] object sqlGeneratorType, [CanB GetString("UnknownOperation", nameof(sqlGeneratorType), nameof(operationType)), sqlGeneratorType, operationType); - /// - /// Non-matching or unknown projection mapping type in set operation ({type1} and {type2}). - /// - public static string UnknownProjectionMappingType([CanBeNull] object type1, [CanBeNull] object type2) - => string.Format( - GetString("UnknownProjectionMappingType", nameof(type1), nameof(type2)), - type1, type2); - /// /// The store type '{type}' used for the column '{column}' in a migration data operation is not supported by the current provider. /// @@ -1186,7 +1158,7 @@ public static string ViewOverrideMismatch([CanBeNull] object propertySpecificati propertySpecification, table); /// - /// VisitChildren must be overridden in class deriving from SqlExpression. + /// 'VisitChildren' must be overridden in the class deriving from 'SqlExpression'. /// public static string VisitChildrenMustBeOverridden => GetString("VisitChildrenMustBeOverridden"); @@ -2293,7 +2265,7 @@ public static EventDefinition LogRevertingMigration([NotNull] IDiagnosti } /// - /// Rolled back to transaction savepoint.. + /// Rolled back to transaction savepoint. /// public static EventDefinition LogRolledBackToTransactionSavepoint([NotNull] IDiagnosticsLogger logger) { diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx index 56bfecae835..6833a3a2df8 100644 --- a/src/EFCore.Relational/Properties/RelationalStrings.resx +++ b/src/EFCore.Relational/Properties/RelationalStrings.resx @@ -127,7 +127,7 @@ The 'DbConnection' is currently in use. The connection can only be changed when the existing connection is not being used. - The given GroupBy pattern is not translatable. Call AsEnumerable before GroupBy to evaluate it locally. + Unable to translate the given 'GroupBy' pattern. Call 'AsEnumerable' before 'GroupBy' to evaluate it client-side. The column '{column}' on table '{table}' has unspecified computed column SQL. Specify the SQL before using Entity Framework to create the database schema. @@ -168,14 +168,11 @@ There is no entity type mapped to the table '{table}' used in a data operation. Either add the corresponding entity type to the model or specify the column types in the data operation. - - Cannot set custom translation on the DbFunction '{function}' since it is an aggregate function. - The provided DbFunction expression '{expression}' is invalid. The expression should be a lambda expression containing a single method call to the target static method. Default values can be provided as arguments if required. E.g. () => SomeClass.SomeMethod(null, 0) - The DbFunction '{function}' is generic. Generic methods are not supported. + The DbFunction '{function}' is generic. Mapping generic methods as a DbFunction is not supported. The DbFunction '{function}' defined on type '{type}' must be either a static method or an instance method defined on a DbContext subclass. Instance methods on other types are not supported. @@ -184,7 +181,7 @@ The DbFunction '{function}' has an invalid return type '{type}'. Owned entity types cannot be used as the return type of a DbFunction. - The DbFunction '{function}' has an invalid return type '{type}'. Non-scalar functions must return IQueryable of a valid entity type. + The DbFunction '{function}' has an invalid return type '{type}'. Non-scalar functions must return 'IQueryable' of a valid entity type. The DbFunction '{function}' does not have a parameter named '{parameter}'. @@ -193,13 +190,13 @@ The parameter '{parameter}' for the DbFunction '{function}' has an invalid type '{type}'. Ensure the parameter type can be mapped by the current provider. - The DbFunction '{function}' returns '{type}', but `{elementType}` is not a mapped entity type. Ensure that `{elementType}` is included in the model. + The DbFunction '{function}' returns '{type}', but '{elementType}' is not a mapped entity type. Ensure that '{elementType}' is included in the model. The DbFunction '{function}' has an invalid return type '{type}'. Ensure that the return type can be mapped by the current provider. - - Cannot set custom translation on the DbFunction '{function}' since it is a table valued function. + + Cannot set custom translation on the DbFunction '{function}' since it is not a scalar function. The column '{column}' on table '{table}' has unspecified default value SQL. Specify the SQL before using Entity Framework to create the database schema. @@ -317,14 +314,11 @@ The required column '{column}' was not present in the results of a 'FromSql' operation. - FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it. Consider calling `AsEnumerable` after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client side. + 'FromSqlRaw' or 'FromSqlInterpolated' was called with non-composable SQL and with a query composing over it. Consider calling 'AsEnumerable' after the method to perform the composition on the client side. The property '{propertySpecification}' has specific configuration for the function '{function}', however it isn't mapped to a column on that function return. Remove the specific configuration or map an entity type that contains this property to '{function}'. - - Data is null. This method or property cannot be called on null values. - Cannot use table '{table}' for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and the comment '{comment}' does not match the comment '{otherComment}'. @@ -359,7 +353,7 @@ The number of values ({valuesCount}) doesn't match the number of columns ({columnsCount}) for the data insertion operation on '{table}'. Provide the same number of values and columns. - Not enough information to uniquely identify outer element in correlated collection scenario. This can happen when trying to correlate on keyless entity or when using 'Distinct' or 'GroupBy' operations without projecting all of the key columns. + Unable to translate collection subquery in projection since the parent query doesn't project key columns of all of it's tables which are required to generate results on client side. This can happen when trying to correlate on keyless entity or when using 'Distinct' or 'GroupBy' operations without projecting all of the key columns. The specified CommandTimeout value is not valid. It must be a positive number. @@ -368,7 +362,7 @@ The specified entity type '{derivedType}' is not derived from '{entityType}'. - Invalid keySelector for GroupBy. + The grouping key '{keySelector}' is of type '{keyType}' which is not valid key. The entity type '{entityType}' is mapped to the DbFunction named '{functionName}' and it's derived from '{baseEntityType}'. Derived entity types cannot be mapped to a function. @@ -389,7 +383,7 @@ The specified MinBatchSize value is not valid. It must be a positive number. - Queries performing '{method}' operation must have a deterministic sort order. Rewrite the query to apply an OrderBy clause on the sequence before calling '{method}'. + Queries performing '{method}' operation must have a deterministic sort order. Rewrite the query to apply an 'OrderBy' clause on the sequence before calling '{method}'. An ambient transaction has been detected. The current provider does not support ambient transactions. See http://go.microsoft.com/fwlink/?LinkId=800142 @@ -572,7 +566,7 @@ Information RelationalEventId.MigrationReverting string - Rolled back to transaction savepoint.. + Rolled back to transaction savepoint. Debug RelationalEventId.RolledBackToTransactionSavepoint @@ -610,6 +604,9 @@ The entity type '{entityType}' is mapped to the DbFunction named '{functionName}', but no DbFunction with that name was found in the model. Ensure that the entity type mapping is configured using the model name of a function in the model. + + Using '{methodName}' on DbSet of '{entityType}' is not supported since '{entityType}' is part of hierarchy and does not contain a discriminator property. + The migration '{migrationName}' was not found. @@ -617,9 +614,9 @@ Entity type '{entityType}' doesn't contain a property mapped to the store-generated concurrency token column '{missingColumn}' that is used by another entity type sharing the table '{table}'. Add a store-generated property mapped to the same column to '{entityType}'. It can be in shadow state. - Collection subquery that uses 'Distinct' or 'Group By' operations must project key columns of all of it's tables. Missing column: {column}. Either add column(s) to the projection or rewrite query to not use 'GroupBy'/'Distinct' operation. + Unable to translate collection subquery in projection since it uses 'Distinct' or 'Group By' operations and doesn't project key columns of all of it's tables which are required to generate results on client side. Missing column: {column}. Either add column(s) to the projection or rewrite query to not use 'GroupBy'/'Distinct' operation. - + Reverse could not be translated to the server because there is no ordering on the server side. @@ -649,8 +646,11 @@ FindMapping on a 'RelationalTypeMappingSource' with a non-relational 'TypeMappingInfo'. - - Using '{memberName}' on DbSet of '{entityType}' is not supported since '{entityType}' is part of hierarchy and does not contain a discriminator property. + + Cannot set 'IsNullable' on DbFunction '{functionName}' since the function does not represent a scalar function. + + + Cannot set 'PropagatesNullability' on parameter '{parameterName}' of DbFunction '{functionName}' since function does not represent a scalar function. Both '{entityType}' and '{otherEntityType}' are mapped to the table '{table}'. All the entity types in a hierarchy that don't have a discriminator must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information. @@ -661,12 +661,6 @@ No relational database providers are configured. Configure a database provider using 'OnConfiguring' or by creating an ImmutableDbContextOptions with a database provider configured and passing it to the context. - - The subquery '{subquery}' references type '{type}' for which no type mapping could be found. - - - Nullability information should only be specified for scalar database functions. - Expression '{sqlExpression}' in SQL tree does not have type mapping assigned. @@ -677,14 +671,11 @@ This connection was used with an ambient transaction. The original ambient transaction needs to be completed before this connection can be used outside of it. - Different projection mapping count in set operation. + Unable to translate set operation when both sides don't assign values to same properties in the nominal type. Please make sure that the properties are inclued on both sides, consider assigning default value if the property doesn't require a specific value. The property '{property}' on entity type '{entityType}' is not mapped to the table '{table}'. - - Unable to identify the concrete entity type to materialize in TPT hierarchy. - The entity type '{entityType}' is not mapped to a table, therefore the entities cannot be persisted to the database. Use 'ToTable' in 'OnModelCreating' to map it. @@ -694,14 +685,11 @@ Cannot create 'SelectExpression' with custom 'TableExpressionBase' since result type '{entityType}' is part of hierarchy and does not contain a discriminator property. - - Sequence contains no elements. - - Can't process set operations after client evaluation, consider moving the operation before the last 'Select' call (see issue #16243). + Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call. - Set operations over different store types are currently unsupported. + Unable to translate set operation when matching columns on both sides have different store types. This LINQ query is being executed in split-query mode. The SQL shown is for the first query to be executed. Additional queries may also be executed depending on the results of the first query. @@ -725,7 +713,7 @@ Timeout must be greater than or equal to zero. Provided: {seconds} seconds. - The underlying reader doesn't have as many fields as expected. + The underlying reader doesn't have as many fields as expected. Expected: {expected}, actual: {actual}. '{entityType}' is mapped to the table '{table}' while '{otherEntityType}' is mapped to the table '{otherTable}'. Map all the entity types in the hierarchy to the same table or remove the discriminator and map all of them to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information. @@ -745,15 +733,12 @@ The query has been configured to use '{splitQueryEnumValue}' and contains a collection in the 'Select' call, which could not be split into separate query. Please remove '{splitQueryMethodName}' if applied or add '{singleQueryMethodName}' to the query. - - Unknown expression '{expression}' of type - '{expressionType}' encountered in '{visitor}'. + + Unhandled expression '{expression}' of type '{expressionType}' encountered in '{visitor}'. The current migration SQL generator '{sqlGeneratorType}' is unable to generate SQL for operations of type '{operationType}'. - - Non-matching or unknown projection mapping type in set operation ({type1} and {type2}). - The store type '{type}' used for the column '{column}' in a migration data operation is not supported by the current provider. @@ -797,6 +782,6 @@ The property '{propertySpecification}' has specific configuration for the view '{table}', however it isn't mapped to a column on that view. Remove the specific configuration or map an entity type that contains this property to '{table}'. - VisitChildren must be overridden in class deriving from SqlExpression. + 'VisitChildren' must be overridden in the class deriving from 'SqlExpression'. \ No newline at end of file diff --git a/src/EFCore.Relational/Query/EntityProjectionExpression.cs b/src/EFCore.Relational/Query/EntityProjectionExpression.cs index 0fa62473ac4..827ffff1a59 100644 --- a/src/EFCore.Relational/Query/EntityProjectionExpression.cs +++ b/src/EFCore.Relational/Query/EntityProjectionExpression.cs @@ -172,7 +172,7 @@ public virtual ColumnExpression BindProperty([NotNull] IProperty property) && !property.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - RelationalStrings.UnableToBindMemberToEntityProjection("Property", property.Name, EntityType.DisplayName())); + RelationalStrings.UnableToBindMemberToEntityProjection("property", property.Name, EntityType.DisplayName())); } return _propertyExpressionMap[property]; @@ -192,7 +192,7 @@ public virtual void AddNavigationBinding([NotNull] INavigation navigation, [NotN && !navigation.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - RelationalStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName())); + RelationalStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } _ownedNavigationMap[navigation] = entityShaper; @@ -212,7 +212,7 @@ public virtual EntityShaperExpression BindNavigation([NotNull] INavigation navig && !navigation.DeclaringEntityType.IsAssignableFrom(EntityType)) { throw new InvalidOperationException( - RelationalStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName())); + RelationalStrings.UnableToBindMemberToEntityProjection("navigation", navigation.Name, EntityType.DisplayName())); } return _ownedNavigationMap.TryGetValue(navigation, out var expression) diff --git a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs index 19984aa1817..690e3ee34a8 100644 --- a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs +++ b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs @@ -1218,7 +1218,7 @@ private void InitializeFields() throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(missingColumns.First())); } - throw new InvalidOperationException(RelationalStrings.TooFewReaderFields); + throw new InvalidOperationException(RelationalStrings.TooFewReaderFields(_columns.Count, FieldCount)); } _columnTypeCases = Enumerable.Repeat(TypeCase.Empty, fieldCount).ToArray(); diff --git a/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs b/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs index 9f4abd8edcd..faeb57393f0 100644 --- a/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs +++ b/src/EFCore.Relational/Query/RelationalEntityShaperExpression.cs @@ -28,14 +28,6 @@ namespace Microsoft.EntityFrameworkCore.Query /// public class RelationalEntityShaperExpression : EntityShaperExpression { - private static readonly MethodInfo _createUnableToIdentifyConcreteTypeException - = typeof(RelationalEntityShaperExpression).GetTypeInfo() - .GetDeclaredMethod(nameof(CreateUnableToIdentifyConcreteTypeException)); - - [UsedImplicitly] - private static Exception CreateUnableToIdentifyConcreteTypeException() - => new InvalidOperationException(RelationalStrings.QueryUnableToIdentifyConcreteTypeInTPT); - /// /// Creates a new instance of the class. /// @@ -94,8 +86,8 @@ protected override LambdaExpression GenerateMaterializationCondition(IEntityType } var defaultBlock = entityType.IsAbstract() - ? Block(Throw(Call(_createUnableToIdentifyConcreteTypeException)), Constant(null, typeof(IEntityType))) - : (Expression)Constant(entityType, typeof(IEntityType)); + ? CreateUnableToDiscriminateExceptionExpression(entityType, discriminatorValueVariable) + : Constant(entityType, typeof(IEntityType)); expressions.Add(Switch(discriminatorValueVariable, defaultBlock, switchCases)); baseCondition = Lambda(Block(new[] { discriminatorValueVariable }, expressions), valueBufferParameter); diff --git a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs index b17922dc7ae..cf9561c1061 100644 --- a/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -882,7 +882,7 @@ protected override ShapedQueryExpression TranslateReverse(ShapedQueryExpression var selectExpression = (SelectExpression)source.QueryExpression; if (selectExpression.Orderings.Count == 0) { - AddTranslationErrorDetails(RelationalStrings.MissingOrderingInSqlExpression); + AddTranslationErrorDetails(RelationalStrings.MissingOrderingInSelectExpression); return null; } diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index f9f551b2109..2187d5ff070 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -757,11 +757,6 @@ public virtual InExpression In(SqlExpression item, SelectExpression subquery, bo var sqlExpression = subquery.Projection.Single().Expression; var typeMapping = sqlExpression.TypeMapping; - if (typeMapping == null) - { - throw new InvalidOperationException(RelationalStrings.NoTypeMappingFoundForSubquery(subquery.Print(), sqlExpression.Type)); - } - item = ApplyTypeMapping(item, typeMapping); return new InExpression(item, subquery, negated, _boolTypeMapping); } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs index 83fd4fb7d58..98739ab10c3 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs @@ -592,7 +592,7 @@ private void AppendGroupBy([NotNull] Expression keySelector) break; default: - throw new InvalidOperationException(RelationalStrings.InvalidKeySelectorForGroupBy); + throw new InvalidOperationException(RelationalStrings.InvalidKeySelectorForGroupBy(keySelector, keySelector.GetType())); } } @@ -879,7 +879,8 @@ private void ApplySetOperation(SetOperationType setOperationType, SelectExpressi if (select1._projectionMapping.Count != select2._projectionMapping.Count) { - // Should not be possible after compiler checks + // For DTO each side can have different projection mapping if some columns are not present. + // We need to project null for missing columns. throw new InvalidOperationException(RelationalStrings.ProjectionMappingCountMismatch); } @@ -895,41 +896,33 @@ private void ApplySetOperation(SetOperationType setOperationType, SelectExpressi HandleEntityProjection(joinedMapping.Key, select1, entityProjection1, select2, entityProjection2); continue; } - - if (joinedMapping.Value1 is SqlExpression innerColumn1 - && joinedMapping.Value2 is SqlExpression innerColumn2) + var innerColumn1 = (SqlExpression)joinedMapping.Value1; + var innerColumn2 = (SqlExpression)joinedMapping.Value2; + // For now, make sure that both sides output the same store type, otherwise the query may fail. + // TODO: with #15586 we'll be able to also allow different store types which are implicitly convertible to one another. + if (innerColumn1.TypeMapping.StoreType != innerColumn2.TypeMapping.StoreType) { - // For now, make sure that both sides output the same store type, otherwise the query may fail. - // TODO: with #15586 we'll be able to also allow different store types which are implicitly convertible to one another. - if (innerColumn1.TypeMapping.StoreType != innerColumn2.TypeMapping.StoreType) - { - throw new InvalidOperationException(RelationalStrings.SetOperationsOnDifferentStoreTypes); - } - - var alias = GenerateUniqueAlias( - joinedMapping.Key.Last?.Name - ?? (innerColumn1 as ColumnExpression)?.Name - ?? "c"); + throw new InvalidOperationException(RelationalStrings.SetOperationsOnDifferentStoreTypes); + } - var innerProjection1 = new ProjectionExpression(innerColumn1, alias); - var innerProjection2 = new ProjectionExpression(innerColumn2, alias); - select1._projection.Add(innerProjection1); - select2._projection.Add(innerProjection2); - var outerProjection = new ColumnExpression(innerProjection1, setExpression); + var alias = GenerateUniqueAlias( + joinedMapping.Key.Last?.Name + ?? (innerColumn1 as ColumnExpression)?.Name + ?? "c"); - if (IsNullableProjection(innerProjection1) - || IsNullableProjection(innerProjection2)) - { - outerProjection = outerProjection.MakeNullable(); - } + var innerProjection1 = new ProjectionExpression(innerColumn1, alias); + var innerProjection2 = new ProjectionExpression(innerColumn2, alias); + select1._projection.Add(innerProjection1); + select2._projection.Add(innerProjection2); + var outerProjection = new ColumnExpression(innerProjection1, setExpression); - _projectionMapping[joinedMapping.Key] = outerProjection; - continue; + if (IsNullableProjection(innerProjection1) + || IsNullableProjection(innerProjection2)) + { + outerProjection = outerProjection.MakeNullable(); } - throw new InvalidOperationException( - RelationalStrings.UnknownProjectionMappingType( - joinedMapping.Value1.GetType().Name, joinedMapping.Value2.GetType().Name)); + _projectionMapping[joinedMapping.Key] = outerProjection; } Offset = null; @@ -1263,7 +1256,7 @@ public Expression AddSingleProjection([NotNull] ShapedQueryExpression shapedQuer Throw( New( typeof(InvalidOperationException).GetConstructors().Single(ci => ci.GetParameters().Count() == 1), - Constant(RelationalStrings.SequenceContainsNoElements))), + Constant(CoreStrings.SequenceContainsNoElements))), Default(shaperExpression.Type)); shaperExpression = Condition( diff --git a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 25e79db6a4c..8cb1157cfd7 100644 --- a/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -178,7 +178,7 @@ protected virtual TableExpressionBase Visit([NotNull] TableExpressionBase tableE default: throw new InvalidOperationException( - RelationalStrings.UnknownExpressionType( + RelationalStrings.UnhandledExpressionInVisitor( tableExpressionBase, tableExpressionBase.GetType(), nameof(SqlNullabilityProcessor))); } } @@ -402,7 +402,7 @@ protected virtual SqlExpression VisitCustomSqlExpression( bool allowOptimizedExpansion, out bool nullable) => throw new InvalidOperationException( - RelationalStrings.UnknownExpressionType(sqlExpression, sqlExpression.GetType(), nameof(SqlNullabilityProcessor))); + RelationalStrings.UnhandledExpressionInVisitor(sqlExpression, sqlExpression.GetType(), nameof(SqlNullabilityProcessor))); /// /// Visits a and computes its nullability. @@ -1114,7 +1114,7 @@ private SqlExpression ProcessJoinPredicate(SqlExpression predicate) } throw new InvalidOperationException( - RelationalStrings.UnknownExpressionType(predicate, predicate.GetType(), nameof(SqlNullabilityProcessor))); + RelationalStrings.UnhandledExpressionInVisitor(predicate, predicate.GetType(), nameof(SqlNullabilityProcessor))); } private SqlExpression OptimizeComparison( diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs index 69a7ff296ee..0bae9edd2c2 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs @@ -122,7 +122,7 @@ public static string IdentityBadType([CanBeNull] object property, [CanBeNull] ob property, entityType, propertyType); /// - /// Include property '{entityType}.{property}' cannot be defined multiple times + /// Include property '{entityType}.{property}' cannot be defined multiple times. /// public static string IncludePropertyDuplicated([CanBeNull] object entityType, [CanBeNull] object property) => string.Format( @@ -130,7 +130,7 @@ public static string IncludePropertyDuplicated([CanBeNull] object entityType, [C entityType, property); /// - /// Include property '{entityType}.{property}' is already included in the index + /// Include property '{entityType}.{property}' is already included in the index. /// public static string IncludePropertyInIndex([CanBeNull] object entityType, [CanBeNull] object property) => string.Format( @@ -138,7 +138,7 @@ public static string IncludePropertyInIndex([CanBeNull] object entityType, [CanB entityType, property); /// - /// Include property '{entityType}.{property}' not found + /// Include property '{entityType}.{property}' not found. /// public static string IncludePropertyNotFound([CanBeNull] object entityType, [CanBeNull] object property) => string.Format( @@ -166,7 +166,7 @@ public static string InvalidColumnNameForFreeText => GetString("InvalidColumnNameForFreeText"); /// - /// The specified table '{table}' is not valid. Specify tables using the format '[schema].[table]'. + /// The specified table '{table}' is not in valid format. Specify tables using the format '[schema].[table]'. /// public static string InvalidTableToIncludeInScaffolding([CanBeNull] object table) => string.Format( @@ -209,28 +209,6 @@ public static string SequenceBadType([CanBeNull] object property, [CanBeNull] ob public static string TransientExceptionDetected => GetString("TransientExceptionDetected"); - /// - /// Unknown operator type encountered in SqlUnaryExpression. - /// - public static string UnknownOperatorTypeInSqlUnaryExpression - => GetString("UnknownOperatorTypeInSqlUnaryExpression"); - - /// - /// Data type '{dataType}' is not supported in this form. Either specify the length explicitly in the type name, for example as '{dataType}(16)', or remove the data type and use APIs such as HasMaxLength to allow Entity Framework choose the data type. - /// - public static string UnqualifiedDataType([CanBeNull] object dataType) - => string.Format( - GetString("UnqualifiedDataType", nameof(dataType)), - dataType); - - /// - /// Data type '{dataType}' for property '{property}' is not supported in this form. Either specify the length explicitly in the type name, for example as '{dataType}(16)', or remove the data type and use APIs such as HasMaxLength to allow Entity Framework choose the data type. - /// - public static string UnqualifiedDataTypeOnProperty([CanBeNull] object dataType, [CanBeNull] object property) - => string.Format( - GetString("UnqualifiedDataTypeOnProperty", nameof(dataType), nameof(property)), - dataType, property); - private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); @@ -354,7 +332,7 @@ public static EventDefinition LogDefaultDecimalTypeColumn([NotNu } /// - /// Found column with table: {tableName}, column name: {columnName}, ordinal: {ordinal}, data type: {dataType}, maximum length: {maxLength}, precision: {precision}, scale: {scale}, nullable: {isNullable}, identity: {isIdentity}, default value: {defaultValue}, computed value: {computedValue}, computed value is stored: {stored} + /// Found column with table: {tableName}, column name: {columnName}, ordinal: {ordinal}, data type: {dataType}, maximum length: {maxLength}, precision: {precision}, scale: {scale}, nullable: {nullable}, identity: {identity}, default value: {defaultValue}, computed value: {computedValue}, computed value is stored: {stored} /// public static FallbackEventDefinition LogFoundColumn([NotNull] IDiagnosticsLogger logger) { @@ -423,7 +401,7 @@ public static EventDefinition LogFoundForeignKey } /// - /// Found index with name: {indexName}, table: {tableName}, is unique: {isUnique}. + /// Found index with name: {indexName}, table: {tableName}, is unique: {unique}. /// public static EventDefinition LogFoundIndex([NotNull] IDiagnosticsLogger logger) { @@ -471,7 +449,7 @@ public static EventDefinition LogFoundPrimaryKey([NotNull] IDiag } /// - /// Found sequence name: {name}, data type: {dataType}, cyclic: {isCyclic}, increment: {increment}, start: {start}, minimum: {min}, maximum: {max}. + /// Found sequence name: {name}, data type: {dataType}, cyclic: {cyclic}, increment: {increment}, start: {start}, minimum: {min}, maximum: {max}. /// public static FallbackEventDefinition LogFoundSequence([NotNull] IDiagnosticsLogger logger) { @@ -612,7 +590,7 @@ public static EventDefinition LogMissingTable([NotNull] IDiagnosticsLogg } /// - /// For foreign key '{foreignKeyName}' on table '{tableName}', unable to find the column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}'. Skipping foreign key. + /// Skipping foreign key '{foreignKeyName}' on table '{tableName}' since the principal column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}' was not found in the model. /// public static EventDefinition LogPrincipalColumnNotFound([NotNull] IDiagnosticsLogger logger) { @@ -636,7 +614,7 @@ public static EventDefinition LogPrincipalColumn } /// - /// For foreign key '{foreignKeyName}' on table '{tableName}', unable to model the end of the foreign key on principal table '{principalTableName}'. This is usually because the principal table was not included in the selection set. + /// Skipping foreign key '{foreignKeyName}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens if the principal table was not included in the selection set. /// public static EventDefinition LogPrincipalTableNotInSelectionSet([NotNull] IDiagnosticsLogger logger) { diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx index bd715339008..a88cdc8fa2d 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx @@ -157,13 +157,13 @@ Identity value generation cannot be used for the property '{property}' on entity type '{entityType}' because the property type is '{propertyType}'. Identity value generation can only be used with signed integer properties. - Include property '{entityType}.{property}' cannot be defined multiple times + Include property '{entityType}.{property}' cannot be defined multiple times. - Include property '{entityType}.{property}' is already included in the index + Include property '{entityType}.{property}' is already included in the index. - Include property '{entityType}.{property}' not found + Include property '{entityType}.{property}' not found. Cannot use table '{table}' for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and entity type '{memoryOptimizedEntityType}' is marked as memory-optimized, but entity type '{nonMemoryOptimizedEntityType}' is not. @@ -175,7 +175,7 @@ The expression passed to the 'propertyReference' parameter of the 'FreeText' method is not a valid reference to a property. The expression should represent a reference to a full-text indexed property on the object referenced in the from clause: 'from e in context.Entities where EF.Functions.FreeText(e.SomeProperty, textToSearchFor) select e' - The specified table '{table}' is not valid. Specify tables using the format '[schema].[table]'. + The specified table '{table}' is not in valid format. Specify tables using the format '[schema].[table]'. The property '{property}' on entity type '{entityType}' is of type 'byte', but is set up to use a SQL Server identity column. This requires that values starting at 255 and counting down will be used for temporary key values. A temporary key value is needed for every entity inserted in a single call to 'SaveChanges'. Care must be taken that these values do not collide with real key values. @@ -194,7 +194,7 @@ Warning SqlServerEventId.DecimalTypeDefaultWarning string string - Found column with table: {tableName}, column name: {columnName}, ordinal: {ordinal}, data type: {dataType}, maximum length: {maxLength}, precision: {precision}, scale: {scale}, nullable: {isNullable}, identity: {isIdentity}, default value: {defaultValue}, computed value: {computedValue}, computed value is stored: {stored} + Found column with table: {tableName}, column name: {columnName}, ordinal: {ordinal}, data type: {dataType}, maximum length: {maxLength}, precision: {precision}, scale: {scale}, nullable: {nullable}, identity: {identity}, default value: {defaultValue}, computed value: {computedValue}, computed value is stored: {stored} Debug SqlServerEventId.ColumnFound string string int string int int int bool bool string string bool? @@ -206,7 +206,7 @@ Debug SqlServerEventId.ForeignKeyFound string string string string - Found index with name: {indexName}, table: {tableName}, is unique: {isUnique}. + Found index with name: {indexName}, table: {tableName}, is unique: {unique}. Debug SqlServerEventId.IndexFound string string bool @@ -214,7 +214,7 @@ Debug SqlServerEventId.PrimaryKeyFound string string - Found sequence name: {name}, data type: {dataType}, cyclic: {isCyclic}, increment: {increment}, start: {start}, minimum: {min}, maximum: {max}. + Found sequence name: {name}, data type: {dataType}, cyclic: {cyclic}, increment: {increment}, start: {start}, minimum: {min}, maximum: {max}. Debug SqlServerEventId.SequenceFound string string bool int long long long @@ -238,11 +238,11 @@ Warning SqlServerEventId.MissingTableWarning string - For foreign key '{foreignKeyName}' on table '{tableName}', unable to find the column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}'. Skipping foreign key. + Skipping foreign key '{foreignKeyName}' on table '{tableName}' since the principal column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}' was not found in the model. Warning SqlServerEventId.ForeignKeyPrincipalColumnMissingWarning string string string string - For foreign key '{foreignKeyName}' on table '{tableName}', unable to model the end of the foreign key on principal table '{principalTableName}'. This is usually because the principal table was not included in the selection set. + Skipping foreign key '{foreignKeyName}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens if the principal table was not included in the selection set. Warning SqlServerEventId.ForeignKeyReferencesMissingPrincipalTableWarning string string string @@ -264,13 +264,4 @@ An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call. - - Unknown operator type encountered in SqlUnaryExpression. - - - Data type '{dataType}' is not supported in this form. Either specify the length explicitly in the type name, for example as '{dataType}(16)', or remove the data type and use APIs such as HasMaxLength to allow Entity Framework choose the data type. - - - Data type '{dataType}' for property '{property}' is not supported in this form. Either specify the length explicitly in the type name, for example as '{dataType}(16)', or remove the data type and use APIs such as HasMaxLength to allow Entity Framework choose the data type. - \ No newline at end of file diff --git a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs index e3547f2ba5e..53c4deef2aa 100644 --- a/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SearchConditionConvertingExpressionVisitor.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.EntityFrameworkCore.SqlServer.Internal; @@ -394,7 +395,8 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio break; default: - throw new InvalidOperationException(SqlServerStrings.UnknownOperatorTypeInSqlUnaryExpression); + throw new InvalidOperationException(RelationalStrings.UnsupportedOperatorForSqlExpression( + sqlUnaryExpression.OperatorType, typeof(SqlUnaryExpression))); } var operand = (SqlExpression)Visit(sqlUnaryExpression.Operand); diff --git a/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerDatabaseModelFactory.cs b/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerDatabaseModelFactory.cs index d2949b99e95..82a578ee6a9 100644 --- a/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerDatabaseModelFactory.cs +++ b/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerDatabaseModelFactory.cs @@ -413,7 +413,7 @@ FROM [sys].[sequences] AS [s] var storeType = reader.GetString("type_name"); var precision = reader.GetValueOrDefault("precision"); var scale = reader.GetValueOrDefault("scale"); - var isCyclic = reader.GetValueOrDefault("is_cycling"); + var cyclic = reader.GetValueOrDefault("is_cycling"); var incrementBy = reader.GetValueOrDefault("increment"); var startValue = reader.GetValueOrDefault("start_value"); var minValue = reader.GetValueOrDefault("minimum_value"); @@ -427,7 +427,7 @@ FROM [sys].[sequences] AS [s] storeType = GetStoreType(storeType, maxLength: 0, precision: precision, scale: scale); - _logger.SequenceFound(DisplayName(schema, name), storeType, isCyclic, incrementBy, startValue, minValue, maxValue); + _logger.SequenceFound(DisplayName(schema, name), storeType, cyclic, incrementBy, startValue, minValue, maxValue); var sequence = new DatabaseSequence { @@ -435,7 +435,7 @@ FROM [sys].[sequences] AS [s] Name = name, Schema = schema, StoreType = storeType, - IsCyclic = isCyclic, + IsCyclic = cyclic, IncrementBy = incrementBy, StartValue = startValue, MinValue = minValue, diff --git a/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs b/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs index cab529d00eb..9985e4d90b6 100644 --- a/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs +++ b/src/EFCore.Sqlite.Core/Internal/SqliteLoggerExtensions.cs @@ -143,13 +143,15 @@ public static void SchemasNotSupportedWarning( /// public static void ForeignKeyReferencesMissingTableWarning( [NotNull] this IDiagnosticsLogger diagnostics, - [CanBeNull] string foreignKeyName) + [CanBeNull] string id, + [CanBeNull] string tableName, + [CanBeNull] string principalTableName) { var definition = SqliteResources.LogForeignKeyScaffoldErrorPrincipalTableNotFound(diagnostics); if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, foreignKeyName); + definition.Log(diagnostics, id, tableName, principalTableName); } // No DiagnosticsSource events because these are purely design-time messages diff --git a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs index a86c372e11a..e9fa97632a9 100644 --- a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs +++ b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs @@ -30,7 +30,7 @@ public static string AggregateOperationNotSupported([CanBeNull] object aggregate aggregateOperator, type); /// - /// Translating this query requires APPLY operation which is not supported on SQLite. + /// Translating this query requires APPLY operation in SQL which is not supported on SQLite. /// public static string ApplyNotSupported => GetString("ApplyNotSupported"); @@ -98,31 +98,31 @@ private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.EntityFrameworkCore.Sqlite.Properties.SqliteStrings", typeof(SqliteResources).Assembly); /// - /// Could not scaffold the foreign key '{foreignKeyName}'. The referenced table could not be found. This most likely occurred because the referenced table was excluded from scaffolding. + /// Skipping foreign key with identity '{id}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens if the principal table was not included in the selection set. /// - public static EventDefinition LogForeignKeyScaffoldErrorPrincipalTableNotFound([NotNull] IDiagnosticsLogger logger) + public static EventDefinition LogForeignKeyScaffoldErrorPrincipalTableNotFound([NotNull] IDiagnosticsLogger logger) { var definition = ((Diagnostics.Internal.SqliteLoggingDefinitions)logger.Definitions).LogForeignKeyScaffoldErrorPrincipalTableNotFound; if (definition == null) { definition = LazyInitializer.EnsureInitialized( ref ((Diagnostics.Internal.SqliteLoggingDefinitions)logger.Definitions).LogForeignKeyScaffoldErrorPrincipalTableNotFound, - () => new EventDefinition( + () => new EventDefinition( logger.Options, SqliteEventId.ForeignKeyReferencesMissingTableWarning, LogLevel.Warning, "SqliteEventId.ForeignKeyReferencesMissingTableWarning", - level => LoggerMessage.Define( + level => LoggerMessage.Define( level, SqliteEventId.ForeignKeyReferencesMissingTableWarning, _resourceManager.GetString("LogForeignKeyScaffoldErrorPrincipalTableNotFound")))); } - return (EventDefinition)definition; + return (EventDefinition)definition; } /// - /// Found column on table: {tableName}, column name: {columnName}, data type: {dataType}, not nullable: {isNotNullable}, default value: {defaultValue}. + /// Found column on table: {tableName}, column name: {columnName}, data type: {dataType}, not nullable: {notNullable}, default value: {defaultValue}. /// public static EventDefinition LogFoundColumn([NotNull] IDiagnosticsLogger logger) { @@ -170,7 +170,7 @@ public static EventDefinition LogFoundForeignKey([ } /// - /// Found index with name: {indexName}, table: {tableName}, is unique: {isUnique}. + /// Found index with name: {indexName}, table: {tableName}, is unique: {unique}. /// public static EventDefinition LogFoundIndex([NotNull] IDiagnosticsLogger logger) { @@ -290,7 +290,7 @@ public static EventDefinition LogMissingTable([NotNull] IDiagnosticsLogg } /// - /// For foreign key with identity '{id}' on table '{tableName}', unable to find the column called '{principalColumnName}' on the foreign key's principal table, '{principaltableName}'. Skipping foreign key. + /// Skipping foreign key with identity '{id}' on table '{tableName}' since the principal column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}' was not found in the model. /// public static EventDefinition LogPrincipalColumnNotFound([NotNull] IDiagnosticsLogger logger) { diff --git a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx index 08bfddf59f3..3977a7098e0 100644 --- a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx +++ b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx @@ -121,7 +121,7 @@ SQLite cannot apply aggregate operator '{aggregateOperator}' on expression of type '{type}'. Convert the values to a supported type or use LINQ to Objects to aggregate the results. - Translating this query requires APPLY operation which is not supported on SQLite. + Translating this query requires APPLY operation in SQL which is not supported on SQLite. '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}' but are configured with different SRIDs. @@ -130,11 +130,11 @@ SQLite does not support this migration operation ('{operation}'). For more information, see http://go.microsoft.com/fwlink/?LinkId=723262. - Could not scaffold the foreign key '{foreignKeyName}'. The referenced table could not be found. This most likely occurred because the referenced table was excluded from scaffolding. - Warning SqliteEventId.ForeignKeyReferencesMissingTableWarning string + Skipping foreign key with identity '{id}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens if the principal table was not included in the selection set. + Warning SqliteEventId.ForeignKeyReferencesMissingTableWarning string string string - Found column on table: {tableName}, column name: {columnName}, data type: {dataType}, not nullable: {isNotNullable}, default value: {defaultValue}. + Found column on table: {tableName}, column name: {columnName}, data type: {dataType}, not nullable: {notNullable}, default value: {defaultValue}. Debug SqliteEventId.ColumnFound string string string bool string @@ -142,7 +142,7 @@ Debug SqliteEventId.ForeignKeyFound string long string string - Found index with name: {indexName}, table: {tableName}, is unique: {isUnique}. + Found index with name: {indexName}, table: {tableName}, is unique: {unique}. Debug SqliteEventId.IndexFound string string bool? @@ -162,7 +162,7 @@ Warning SqliteEventId.MissingTableWarning string - For foreign key with identity '{id}' on table '{tableName}', unable to find the column called '{principalColumnName}' on the foreign key's principal table, '{principaltableName}'. Skipping foreign key. + Skipping foreign key with identity '{id}' on table '{tableName}' since the principal column called '{principalColumnName}' on the foreign key's principal table, '{principalTableName}' was not found in the model. Warning SqliteEventId.ForeignKeyPrincipalColumnMissingWarning string string string string diff --git a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs index 304e95f3c08..1cdbe2df1bb 100644 --- a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs +++ b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs @@ -525,7 +525,7 @@ private void GetForeignKeys(DbConnection connection, DatabaseTable table, IList< if (foreignKey.PrincipalTable == null) { - _logger.ForeignKeyReferencesMissingTableWarning(id.ToString()); + _logger.ForeignKeyReferencesMissingTableWarning(id.ToString(), table.Name, principalTableName); continue; } diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 8597d9e4639..d8c1c240a7b 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -431,7 +431,7 @@ public static void QueryExecutionPlanned( if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics, expressionPrinter.Print(queryExecutorExpression)); + definition.Log(diagnostics, Environment.NewLine, expressionPrinter.Print(queryExecutorExpression)); } if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) @@ -448,9 +448,9 @@ public static void QueryExecutionPlanned( private static string QueryExecutionPlanned(EventDefinitionBase definition, EventData payload) { - var d = (EventDefinition)definition; + var d = (EventDefinition)definition; var p = (QueryExpressionEventData)payload; - return d.GenerateMessage(p.ExpressionPrinter.Print(p.Expression)); + return d.GenerateMessage(Environment.NewLine, p.ExpressionPrinter.Print(p.Expression)); } /// diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs index 7430f889679..f505cd69957 100644 --- a/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/EFCore/Properties/CoreStrings.Designer.cs @@ -959,7 +959,7 @@ public static string FullChangeTrackingRequired([CanBeNull] object entityType, [ entityType, changeTrackingStrategy, fullStrategy, fullPlusStrategy); /// - /// The '{methodName}' method is not supported because the query has switched to client-evaluation. Inspect the log to determine which query expressions are triggering client-evaluation. + /// The '{methodName}' method is not supported because the query has switched to client-evaluation. This usually happens when the arguments to the method cannot be translated to server. Rewrite the query to avoid client evaluation of arguments so that method can be translated to server. /// public static string FunctionOnClient([CanBeNull] object methodName) => string.Format( @@ -1035,19 +1035,21 @@ public static string ImplementationTypeRequired([CanBeNull] object service) service); /// - /// 'Include' is not supported on entity type '{entityType}' because it has a defining query. + /// The 'Include' operation with argument '{expression}' is not supported on entity type '{entityType}' because it has a defining query. /// [Obsolete] - public static string IncludeOnEntityWithDefiningQueryNotSupported([CanBeNull] object entityType) + public static string IncludeOnEntityWithDefiningQueryNotSupported([CanBeNull] object expression, [CanBeNull] object entityType) => string.Format( - GetString("IncludeOnEntityWithDefiningQueryNotSupported", nameof(entityType)), - entityType); + GetString("IncludeOnEntityWithDefiningQueryNotSupported", nameof(expression), nameof(entityType)), + expression, entityType); /// - /// Include has been used on a non-entity queryable. + /// Cannot apply the 'Include' operation with argument '{expression}'. Either the source is not a queryable of a known entity type or 'Include' has been applied after 'Select' method which projects a different entity type through navigation. Consider applying 'Include' before 'Select' method call. /// - public static string IncludeOnNonEntity - => GetString("IncludeOnNonEntity"); + public static string IncludeOnNonEntity([CanBeNull] object expression) + => string.Format( + GetString("IncludeOnNonEntity", nameof(expression)), + expression); /// /// The Include path '{navigationName}->{inverseNavigationName}' results in a cycle. Cycles are not allowed in no-tracking queries; either use a tracking query or remove the cycle. @@ -1138,7 +1140,7 @@ public static string InvalidEnumValue([CanBeNull] object argumentName, [CanBeNul argumentName, enumType); /// - /// The expression '{expression}' is invalid inside an Include operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393. + /// The expression '{expression}' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393. /// public static string InvalidIncludeExpression([CanBeNull] object expression) => string.Format( @@ -1153,12 +1155,6 @@ public static string InvalidKeyValue([CanBeNull] object entityType, [CanBeNull] GetString("InvalidKeyValue", nameof(entityType), nameof(keyProperty)), entityType, keyProperty); - /// - /// The lambda expression used inside 'Include' is not valid. - /// - public static string InvalidLambdaExpressionInsideInclude - => GetString("InvalidLambdaExpressionInsideInclude"); - /// /// The expression '{expression}' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. /// @@ -1167,12 +1163,6 @@ public static string InvalidMemberExpression([CanBeNull] object expression) GetString("InvalidMemberExpression", nameof(expression)), expression); - /// - /// Unhandled operation: MemberInitExpression binding is not a MemberAssignment - /// - public static string InvalidMemberInitBinding - => GetString("InvalidMemberInitBinding"); - /// /// The expression '{expression}' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. When specifying multiple properties or fields, use an anonymous type: 't => new {{ t.MyProperty, t.MyField }}'. /// @@ -1294,10 +1284,12 @@ public static string InvalidType([CanBeNull] object property, [CanBeNull] object property, entityType, valueType, propertyType); /// - /// Invalid type conversion specified in an 'Include' operation. + /// Unable to include navigation chain '{includeExpression}' specified by 'Include' operation as the converted type '{type}' is not part of model. /// - public static string InvalidTypeConversationWithInclude - => GetString("InvalidTypeConversationWithInclude"); + public static string InvalidTypeConversationWithInclude([CanBeNull] object includeExpression, [CanBeNull] object type) + => string.Format( + GetString("InvalidTypeConversationWithInclude", nameof(includeExpression), nameof(type)), + includeExpression, type); /// /// A call was made to '{useService}', but Entity Framework is not building its own internal service provider. Either allow Entity Framework to build the service provider by removing the call to '{useInternalServiceProvider}', or build the '{service}' services to use into the service provider before passing it to '{useInternalServiceProvider}'. @@ -1332,7 +1324,7 @@ public static string InverseToOwnedType([CanBeNull] object principalEntityType, principalEntityType, navigation, ownedType, ownerType); /// - /// The source IQueryable doesn't implement IAsyncEnumerable<{genericParameter}>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations. + /// The source 'IQueryable' doesn't implement 'IAsyncEnumerable<{genericParameter}>'. Only sources that implement 'IAsyncEnumerable' can be used for Entity Framework asynchronous operations. /// public static string IQueryableNotAsync([CanBeNull] object genericParameter) => string.Format( @@ -1340,7 +1332,7 @@ public static string IQueryableNotAsync([CanBeNull] object genericParameter) genericParameter); /// - /// The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IAsyncQueryProvider can be used for Entity Framework asynchronous operations. + /// The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations. /// public static string IQueryableProviderNotAsync => GetString("IQueryableProviderNotAsync"); @@ -2130,7 +2122,7 @@ public static string QueryContextAlreadyInitializedStateManager => GetString("QueryContextAlreadyInitializedStateManager"); /// - /// The materialization condition passed for entity shaper of entity type '{entityType}' is not of the correct shape. A materialization condition must be a LambdaExpression of 'Func<ValueBuffer, IEntityType>' + /// The materialization condition passed for entity shaper of entity type '{entityType}' is not of the correct shape. A materialization condition must be a 'LambdaExpression' of 'Func<ValueBuffer, IEntityType>' /// public static string QueryEntityMaterializationConditionWrongShape([CanBeNull] object entityType) => string.Format( @@ -2146,7 +2138,7 @@ public static string QueryFailed([CanBeNull] object expression, [CanBeNull] obje expression, visitor); /// - /// The query contains a final projection '{projection}' to type '{queryableType}'. Collections in the final projection must be an 'IEnumerable<T>' type such as 'List<T>'. Consider using 'ToList' or some other mechanism to convert the 'IQueryable<T>' or 'IOrderedEnumerable<T>' into an 'IEnumerable<T>'. + /// The query contains a projection '{projection}' of type '{queryableType}'. Collections in the final projection must be an 'IEnumerable<T>' type such as 'List<T>'. Consider using 'ToList' or some other mechanism to convert the 'IQueryable<T>' or 'IOrderedEnumerable<T>' into an 'IEnumerable<T>'. /// public static string QueryInvalidMaterializationType([CanBeNull] object projection, [CanBeNull] object queryableType) => string.Format( @@ -2170,7 +2162,7 @@ public static string QueryUnableToTranslateMember([CanBeNull] object member, [Ca member, entityType); /// - /// Translation of method '{declaringTypeName}.{methodName}' failed. If you are trying to map your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. + /// Translation of method '{declaringTypeName}.{methodName}' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. /// public static string QueryUnableToTranslateMethod([CanBeNull] object declaringTypeName, [CanBeNull] object methodName) => string.Format( @@ -2264,7 +2256,7 @@ public static string RetryLimitExceeded([CanBeNull] object retryLimit, [CanBeNul retryLimit, strategy); /// - /// Runtime parameter extraction lambda must have one QueryContext parameter. + /// While registering a runtime parameter, the lambda expression must have only one parameter which must be same as 'QueryCompilationContext.QueryContextParameter' expression. /// public static string RuntimeParameterMissingParameter => GetString("RuntimeParameterMissingParameter"); @@ -2400,7 +2392,7 @@ public static string ServiceProviderConfigRemoved([CanBeNull] object key) key); /// - /// When performing a set operation, both operands must have the same 'Include' operations. + /// Unable to translate set operation since both operands have different 'Include' operations. Consider having same 'Include' applied on both sides. /// public static string SetOperationWithDifferentIncludesInOperands => GetString("SetOperationWithDifferentIncludesInOperands"); @@ -2580,7 +2572,7 @@ public static string TypeNotMarkedAsShared([CanBeNull] object type) type); /// - /// Unable to materialize entity of type '{entityType}'. No discriminators matched '{discriminator}'. + /// Unable to materialize entity instance of type '{entityType}'. No discriminators matched the discriminator value '{discriminator}'. /// public static string UnableToDiscriminate([CanBeNull] object entityType, [CanBeNull] object discriminator) => string.Format( @@ -2620,7 +2612,7 @@ public static string UnhandledNavigationBase([CanBeNull] object type) type); /// - /// Unknown {entity}. + /// Unhandled {entity} encounted. /// public static string UnknownEntity([CanBeNull] object entity) => string.Format( @@ -2676,7 +2668,7 @@ public static string ValueGenWithConversion([CanBeNull] object entityType, [CanB entityType, property, converter); /// - /// Calling '{visitMethodName}' is not allowed. Visit the expression manually for the relevant part. + /// Calling '{visitMethodName}' is not allowed. Visit the expression manually for the relevant part in the visitor. /// public static string VisitIsNotAllowed([CanBeNull] object visitMethodName) => string.Format( @@ -3230,7 +3222,7 @@ public static EventDefinition LogExecutionStrategyRetryi } /// - /// The query uses the First/FirstOrDefault operator without OrderBy and filter operators. This may lead to unpredictable results. + /// The query uses the 'First'/'FirstOrDefault' operator without 'OrderBy' and filter operators. This may lead to unpredictable results. /// public static EventDefinition LogFirstWithoutOrderByAndFilter([NotNull] IDiagnosticsLogger logger) { @@ -3374,7 +3366,7 @@ public static EventDefinition LogIncompatibleMat } /// - /// Invalid Include path '{navigationChain}': couldn't find navigation for '{navigationName}'. + /// Unable to find navigation '{1_navigation}' specified in string based include path '{0_navigationChain}'. /// public static EventDefinition LogInvalidIncludePath([NotNull] IDiagnosticsLogger logger) { @@ -3857,27 +3849,27 @@ public static EventDefinition LogQueryCompilationStarting([NotNu } /// - /// {plan} + /// Generated query execution expression: {newline}'{plan}' /// - public static EventDefinition LogQueryExecutionPlanned([NotNull] IDiagnosticsLogger logger) + public static EventDefinition LogQueryExecutionPlanned([NotNull] IDiagnosticsLogger logger) { var definition = ((LoggingDefinitions)logger.Definitions).LogQueryExecutionPlanned; if (definition == null) { definition = LazyInitializer.EnsureInitialized( ref ((LoggingDefinitions)logger.Definitions).LogQueryExecutionPlanned, - () => new EventDefinition( + () => new EventDefinition( logger.Options, CoreEventId.QueryExecutionPlanned, LogLevel.Debug, "CoreEventId.QueryExecutionPlanned", - level => LoggerMessage.Define( + level => LoggerMessage.Define( level, CoreEventId.QueryExecutionPlanned, _resourceManager.GetString("LogQueryExecutionPlanned")))); } - return (EventDefinition)definition; + return (EventDefinition)definition; } /// @@ -4124,7 +4116,7 @@ public static EventDefinition LogRequiredAttributeOnSkipNavigati } /// - /// The query uses a row limiting operator (Skip/Take) without an OrderBy operator. This may lead to unpredictable results. + /// The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. /// public static EventDefinition LogRowLimitingOperationWithoutOrderBy([NotNull] IDiagnosticsLogger logger) { diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx index 9d3c27e5abc..9aa1fdd3aec 100644 --- a/src/EFCore/Properties/CoreStrings.resx +++ b/src/EFCore/Properties/CoreStrings.resx @@ -475,7 +475,7 @@ The entity type '{entityType}' is configured to use the '{changeTrackingStrategy}' change tracking strategy when full change tracking notifications are required. Use 'ModelBuilder.HasChangeTrackingStrategy' in 'OnModelCreating' to configure all entity types in the model to use the '{fullStrategy}' or '{fullPlusStrategy}' strategy. - The '{methodName}' method is not supported because the query has switched to client-evaluation. Inspect the log to determine which query expressions are triggering client-evaluation. + The '{methodName}' method is not supported because the query has switched to client-evaluation. This usually happens when the arguments to the method cannot be translated to server. Rewrite the query to avoid client evaluation of arguments so that method can be translated to server. The edge cannot be added because the graph does not contain vertex '{vertex}'. @@ -505,11 +505,11 @@ The implementation type for the registration of the '{service}' service could not be determined. Specific implementation types must be used for services that expect multiple registrations so as to avoid duplicates. - 'Include' is not supported on entity type '{entityType}' because it has a defining query. + The 'Include' operation with argument '{expression}' is not supported on entity type '{entityType}' because it has a defining query. Obsolete - Include has been used on a non-entity queryable. + Cannot apply the 'Include' operation with argument '{expression}'. Either the source is not a queryable of a known entity type or 'Include' has been applied after 'Select' method which projects a different entity type through navigation. Consider applying 'Include' before 'Select' method call. The Include path '{navigationName}->{inverseNavigationName}' results in a cycle. Cycles are not allowed in no-tracking queries; either use a tracking query or remove the cycle. @@ -545,20 +545,14 @@ The value provided for argument '{argumentName}' must be a valid value of enum type '{enumType}'. - The expression '{expression}' is invalid inside an Include operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393. + The expression '{expression}' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393. Unable to track an entity of type '{entityType}' because its primary key property '{keyProperty}' is null. - - The lambda expression used inside 'Include' is not valid. - The expression '{expression}' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. - - Unhandled operation: MemberInitExpression binding is not a MemberAssignment - The expression '{expression}' is not a valid member access expression. The expression should represent a simple property or field access: 't => t.MyProperty'. When specifying multiple properties or fields, use an anonymous type: 't => new {{ t.MyProperty, t.MyField }}'. @@ -607,7 +601,7 @@ The value for property '{1_entityType}.{0_property}' cannot be set to a value of type '{valueType}' because its type is '{propertyType}'. - Invalid type conversion specified in an 'Include' operation. + Unable to include navigation chain '{includeExpression}' specified by 'Include' operation as the converted type '{type}' is not part of model. A call was made to '{useService}', but Entity Framework is not building its own internal service provider. Either allow Entity Framework to build the service provider by removing the call to '{useInternalServiceProvider}', or build the '{service}' services to use into the service provider before passing it to '{useInternalServiceProvider}'. @@ -622,10 +616,10 @@ The navigation '{principalEntityType}.{navigation}' is not supported because it is pointing to an owned entity type '{ownedType}'. Only the ownership navigation from the entity type '{ownerType}' can point to the owned entity type. - The source IQueryable doesn't implement IAsyncEnumerable<{genericParameter}>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations. + The source 'IQueryable' doesn't implement 'IAsyncEnumerable<{genericParameter}>'. Only sources that implement 'IAsyncEnumerable' can be used for Entity Framework asynchronous operations. - The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IAsyncQueryProvider can be used for Entity Framework asynchronous operations. + The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations. The derived type '{derivedType}' cannot have the [Key] attribute on property '{property}' since primary keys may only be declared on the root type. @@ -741,7 +735,7 @@ Information CoreEventId.ExecutionStrategyRetrying int string Exception - The query uses the First/FirstOrDefault operator without OrderBy and filter operators. This may lead to unpredictable results. + The query uses the 'First'/'FirstOrDefault' operator without 'OrderBy' and filter operators. This may lead to unpredictable results. Warning CoreEventId.FirstWithoutOrderByAndFilterWarning @@ -765,7 +759,7 @@ Debug CoreEventId.IncompatibleMatchingForeignKeyProperties string string string string - Invalid Include path '{navigationChain}': couldn't find navigation for '{navigationName}'. + Unable to find navigation '{1_navigation}' specified in string based include path '{0_navigationChain}'. Error CoreEventId.InvalidIncludePathError object object @@ -845,8 +839,8 @@ Debug CoreEventId.QueryCompilationStarting string string - {plan} - Debug CoreEventId.QueryExecutionPlanned string + Generated query execution expression: {newline}'{plan}' + Debug CoreEventId.QueryExecutionPlanned string string 'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't called in the DbContext options configuration. Consider removing the 'AddEntityFramework*' call, as in most cases it's not needed and may cause conflicts with other products and services registered in the same service provider. @@ -889,7 +883,7 @@ Debug CoreEventId.RequiredAttributeOnSkipNavigation string string - The query uses a row limiting operator (Skip/Take) without an OrderBy operator. This may lead to unpredictable results. + The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. Warning CoreEventId.RowLimitingOperationWithoutOrderByWarning @@ -1224,13 +1218,13 @@ The 'InitializeStateManager' method has been called multiple times on the current query context. This method is intended to be called only once before query enumeration starts. - The materialization condition passed for entity shaper of entity type '{entityType}' is not of the correct shape. A materialization condition must be a LambdaExpression of 'Func<ValueBuffer, IEntityType>' + The materialization condition passed for entity shaper of entity type '{entityType}' is not of the correct shape. A materialization condition must be a 'LambdaExpression' of 'Func<ValueBuffer, IEntityType>' Processing of the LINQ expression '{expression}' by '{visitor}' failed. This may indicate either a bug or a limitation in Entity Framework. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information. - The query contains a final projection '{projection}' to type '{queryableType}'. Collections in the final projection must be an 'IEnumerable<T>' type such as 'List<T>'. Consider using 'ToList' or some other mechanism to convert the 'IQueryable<T>' or 'IOrderedEnumerable<T>' into an 'IEnumerable<T>'. + The query contains a projection '{projection}' of type '{queryableType}'. Collections in the final projection must be an 'IEnumerable<T>' type such as 'List<T>'. Consider using 'ToList' or some other mechanism to convert the 'IQueryable<T>' or 'IOrderedEnumerable<T>' into an 'IEnumerable<T>'. Translation of '{expression}' failed. Either the query source is not an entity type, or the specified property does not exist on the entity type. @@ -1239,7 +1233,7 @@ Translation of member '{member}' on entity type '{entityType}' failed. This commonly occurs when the specified member is unmapped. - Translation of method '{declaringTypeName}.{methodName}' failed. If you are trying to map your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. + Translation of method '{declaringTypeName}.{methodName}' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Translation of the 'string.Equals' overload with a 'StringComparison' parameter is not supported. See https://go.microsoft.com/fwlink/?linkid=2129535 for more information. @@ -1278,7 +1272,7 @@ The maximum number of retries ({retryLimit}) was exceeded while executing database operations with '{strategy}'. See the inner exception for the most recent failure. - Runtime parameter extraction lambda must have one QueryContext parameter. + While registering a runtime parameter, the lambda expression must have only one parameter which must be same as 'QueryCompilationContext.QueryContextParameter' expression. The seed entity for entity type '{entityType}' cannot be added because a default value was provided for the required property '{property}'. Please provide a value different from '{defaultValue}'. @@ -1332,7 +1326,7 @@ configuration removed for '{key}' - When performing a set operation, both operands must have the same 'Include' operations. + Unable to translate set operation since both operands have different 'Include' operations. Consider having same 'Include' applied on both sides. The entity type '{entityType}' is in shadow state. A valid model requires all entity types to have corresponding CLR type. @@ -1401,7 +1395,7 @@ The type '{type}' is not been configured as a shared type in the model. Before calling 'UsingEntity', please mark the type as shared or add the entity type in the model as a shared entity. - Unable to materialize entity of type '{entityType}'. No discriminators matched '{discriminator}'. + Unable to materialize entity instance of type '{entityType}'. No discriminators matched the discriminator value '{discriminator}'. Unable to set IsUnique to '{isUnique}' on the relationship underlying the navigation '{2_entityType}.{1_navigationName}' because the navigation has the opposite multiplicity. @@ -1416,7 +1410,7 @@ Unhandled 'INavigationBase' of type '{type}'. - Unknown {entity}. + Unhandled {entity} encounted. The value of '{entityType}.{property}' is unknown when attempting to save changes. This is because the property is also part of a foreign key for which the principal entity in the relationship is not known. @@ -1437,7 +1431,7 @@ Value generation is not supported for property '{entityType}.{property}' because it has a '{converter}' converter configured. Configure the property to not use value generation using 'ValueGenerated.Never' or 'DatabaseGeneratedOption.None' and specify explicit values instead. - Calling '{visitMethodName}' is not allowed. Visit the expression manually for the relevant part. + Calling '{visitMethodName}' is not allowed. Visit the expression manually for the relevant part in the visitor. An error was generated for warning '{eventName}': {message} This exception can be suppressed or logged by passing event ID '{eventId}' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'. diff --git a/src/EFCore/Query/EntityShaperExpression.cs b/src/EFCore/Query/EntityShaperExpression.cs index 937d7199ffe..3fd1cc92700 100644 --- a/src/EFCore/Query/EntityShaperExpression.cs +++ b/src/EFCore/Query/EntityShaperExpression.cs @@ -86,6 +86,20 @@ protected EntityShaperExpression( MaterializationCondition = materializationCondition; } + /// + /// Creates an expression to throw an exception when unable to determine entity type + /// to materialize based on discriminator value. + /// + /// The entity type for which materialization was requested. + /// The expression containing value of discriminator. + /// An expression of representing materilization condition for the entity type. + protected static Expression CreateUnableToDiscriminateExceptionExpression([NotNull] IEntityType entityType, [NotNull] Expression discriminatorValue) + => Block( + Throw(Call(_createUnableToDiscriminateException, + Constant(Check.NotNull(entityType, nameof(entityType))), + Convert(Check.NotNull(discriminatorValue, nameof(discriminatorValue)), typeof(object)))), + Constant(null, typeof(IEntityType))); + /// /// Creates an expression of to determine which entity type to materialize. /// @@ -111,12 +125,7 @@ protected virtual LambdaExpression GenerateMaterializationCondition([NotNull] IE discriminatorProperty.ClrType, discriminatorProperty.GetIndex(), discriminatorProperty)) }; - var exception = Block( - Throw( - Call( - _createUnableToDiscriminateException, Constant(entityType), - Convert(discriminatorValueVariable, typeof(object)))), - Constant(null, typeof(IEntityType))); + var exception = CreateUnableToDiscriminateExceptionExpression(entityType, discriminatorValueVariable); var discriminatorComparer = discriminatorProperty.GetKeyValueComparer(); if (discriminatorComparer.IsDefault()) diff --git a/src/EFCore/Query/ExpressionPrinter.cs b/src/EFCore/Query/ExpressionPrinter.cs index 38b466d8895..97edc992c9b 100644 --- a/src/EFCore/Query/ExpressionPrinter.cs +++ b/src/EFCore/Query/ExpressionPrinter.cs @@ -598,7 +598,8 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp { for (var i = 0; i < memberInitExpression.Bindings.Count; i++) { - if (memberInitExpression.Bindings[i] is MemberAssignment assignment) + var binding = memberInitExpression.Bindings[i]; + if (binding is MemberAssignment assignment) { _stringBuilder.Append(assignment.Member.Name + " = "); Visit(assignment.Expression); @@ -606,7 +607,7 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp } else { - AppendLine(CoreStrings.InvalidMemberInitBinding); + AppendLine(CoreStrings.UnhandledMemberBinding(binding.BindingType)); } } } diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs index 45abd7413df..8da56015b88 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs @@ -827,7 +827,7 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi { throw new InvalidOperationException( #pragma warning disable CS0612 // Type or member is obsolete - CoreStrings.IncludeOnEntityWithDefiningQueryNotSupported(entityReference.EntityType.DisplayName())); + CoreStrings.IncludeOnEntityWithDefiningQueryNotSupported(expression, entityReference.EntityType.DisplayName())); #pragma warning restore CS0612 // Type or member is obsolete } #pragma warning restore CS0618 // Type or member is obsolete @@ -869,11 +869,6 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi var (result, filterExpression) = ExtractIncludeFilter(includeLambda.Body, includeLambda.Body); var lastIncludeTree = PopulateIncludeTree(currentIncludeTreeNode, result); - if (lastIncludeTree == null) - { - throw new InvalidOperationException(CoreStrings.InvalidLambdaExpressionInsideInclude); - } - if (filterExpression != null) { if (lastIncludeTree.FilterExpression != null @@ -894,7 +889,7 @@ private NavigationExpansionExpression ProcessInclude(NavigationExpansionExpressi return source; } - throw new InvalidOperationException(CoreStrings.IncludeOnNonEntity); + throw new InvalidOperationException(CoreStrings.IncludeOnNonEntity(expression.Print())); static (Expression result, LambdaExpression filterExpression) ExtractIncludeFilter( Expression currentExpression, @@ -1749,7 +1744,8 @@ private IncludeTreeNode PopulateIncludeTree(IncludeTreeNode includeTreeNode, Exp .FirstOrDefault(et => et.ClrType == convertedType); if (entityType == null) { - throw new InvalidOperationException(CoreStrings.InvalidTypeConversationWithInclude); + throw new InvalidOperationException( + CoreStrings.InvalidTypeConversationWithInclude(expression, convertedType.ShortDisplayName())); } } @@ -1778,7 +1774,7 @@ private IncludeTreeNode PopulateIncludeTree(IncludeTreeNode includeTreeNode, Exp break; } - return null; + throw new InvalidOperationException(CoreStrings.InvalidIncludeExpression(expression)); } private Expression Reduce(Expression source) diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs index 7434ac6b008..8b3fc042d38 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs @@ -1153,7 +1153,7 @@ public override async Task Projecting_after_navigation_and_distinct_throws(bool public override Task Reverse_without_explicit_ordering_throws(bool async) { return AssertTranslationFailedWithDetails( - () => base.Reverse_without_explicit_ordering_throws(async), CosmosStrings.MissingOrderingInSqlExpression); + () => base.Reverse_without_explicit_ordering_throws(async), CosmosStrings.MissingOrderingInSelectExpression); } [ConditionalTheory(Skip = "Cross collection join Issue#17246")] diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs index a7af72b8175..71eaf72211d 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/QueryLoggingCosmosTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Linq; using Microsoft.EntityFrameworkCore.Cosmos.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Diagnostics; @@ -38,7 +39,7 @@ var customers "Compiling query expression: ", Fixture.TestSqlLoggerFactory.Log[0].Message); Assert.StartsWith( - "queryContext => new QueryingEnumerable(", + "Generated query execution expression: " + Environment.NewLine + "'queryContext => new QueryingEnumerable(", Fixture.TestSqlLoggerFactory.Log[1].Message); } diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs index 9fcd44330cc..8485ea7484f 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeNoTrackingQueryTestBase.cs @@ -122,7 +122,7 @@ var orders public override Task Include_collection_with_last_no_orderby(bool async) { return AssertTranslationFailedWithDetails( - () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSqlExpression); + () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSelectExpression); } [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] diff --git a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs index eabdeb30e3c..1bf45c0b5cf 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/NorthwindSplitIncludeQueryTestBase.cs @@ -110,7 +110,7 @@ var orders public override Task Include_collection_with_last_no_orderby(bool async) { return AssertTranslationFailedWithDetails( - () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSqlExpression); + () => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSelectExpression); } [ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")] diff --git a/test/EFCore.Relational.Specification.Tests/Query/TPTInheritanceQueryTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/TPTInheritanceQueryTestBase.cs index 5581b96339d..566447d77f3 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/TPTInheritanceQueryTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/TPTInheritanceQueryTestBase.cs @@ -48,12 +48,12 @@ public virtual void Using_from_sql_throws() var message = Assert.Throws(() => context.Set().FromSqlRaw("Select * from Birds")).Message; - Assert.Equal(RelationalStrings.NonTPHOnFromSqlNotSupported("FromSqlRaw", typeof(Bird).Name), message); + Assert.Equal(RelationalStrings.MethodOnNonTPHRootNotSupported("FromSqlRaw", typeof(Bird).Name), message); message = Assert.Throws(() => context.Set().FromSqlInterpolated($"Select * from Birds")) .Message; - Assert.Equal(RelationalStrings.NonTPHOnFromSqlNotSupported("FromSqlInterpolated", typeof(Bird).Name), message); + Assert.Equal(RelationalStrings.MethodOnNonTPHRootNotSupported("FromSqlInterpolated", typeof(Bird).Name), message); } protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) diff --git a/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs b/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs index d39a5c10108..67fdb44b406 100644 --- a/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs +++ b/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs @@ -807,25 +807,25 @@ public void DbFunction_Queryable_custom_translation() Assert.Null(dbFunctionBuilder.Metadata.Translation); Assert.Equal( - RelationalStrings.DbFunctionTableValuedCustomTranslation(methodInfo.DisplayName()), + RelationalStrings.DbFunctionNonScalarCustomTranslation(methodInfo.DisplayName()), Assert.Throws( () => dbFunctionBuilder.HasTranslation(args => new SqlFragmentExpression("Empty"))).Message); var dbFunction = dbFunctionBuilder.Metadata; Assert.Equal( - RelationalStrings.DbFunctionTableValuedCustomTranslation(methodInfo.DisplayName()), + RelationalStrings.DbFunctionNonScalarCustomTranslation(methodInfo.DisplayName()), Assert.Throws( () => ((IConventionDbFunction)dbFunction).SetTranslation(args => new SqlFragmentExpression("Empty"))).Message); Assert.Equal( - RelationalStrings.DbFunctionTableValuedCustomTranslation(methodInfo.DisplayName()), + RelationalStrings.DbFunctionNonScalarCustomTranslation(methodInfo.DisplayName()), Assert.Throws( () => ((IConventionDbFunction)dbFunction) .SetTranslation(args => new SqlFragmentExpression("Empty"), fromDataAnnotation: true)).Message); Assert.Equal( - RelationalStrings.DbFunctionTableValuedCustomTranslation(methodInfo.DisplayName()), + RelationalStrings.DbFunctionNonScalarCustomTranslation(methodInfo.DisplayName()), Assert.Throws( () => dbFunction.Translation = args => new SqlFragmentExpression("Empty")).Message); } diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index dfbd3231b98..984b36e199b 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -6637,7 +6637,7 @@ public virtual Task Collection_navigation_ofType_filter_works(bool async) public virtual async Task Include_after_select_with_cast_throws(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("h => h.Commander"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -6650,7 +6650,7 @@ public virtual async Task Include_after_select_with_cast_throws(bool async) public virtual async Task Include_after_select_with_entity_projection_throws(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("c => c.BornGears"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -6662,7 +6662,7 @@ public virtual async Task Include_after_select_with_entity_projection_throws(boo public virtual async Task Include_after_select_anonymous_projection_throws(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("x => x.f.Capital"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -6674,7 +6674,7 @@ public virtual async Task Include_after_select_anonymous_projection_throws(bool public virtual async Task Include_after_Select_throws(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("h => h.Capital"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -6686,7 +6686,7 @@ public virtual async Task Include_after_Select_throws(bool async) public virtual async Task Include_after_SelectMany_throws(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("g => g.Squad"), (await Assert.ThrowsAsync( () => AssertQuery( async, diff --git a/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs index 1f70eb28e37..09fed498ea5 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs @@ -59,7 +59,7 @@ await AssertQuery( public virtual async Task Include_property_after_navigation(bool async) { Assert.Equal( - CoreStrings.InvalidLambdaExpressionInsideInclude, + CoreStrings.InvalidIncludeExpression("o.Customer.CustomerID"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -71,7 +71,7 @@ public virtual async Task Include_property_after_navigation(bool async) public virtual async Task Include_property(bool async) { Assert.Equal( - CoreStrings.InvalidLambdaExpressionInsideInclude, + CoreStrings.InvalidIncludeExpression("o.OrderDate"), (await Assert.ThrowsAsync( () => AssertQuery( async, @@ -1251,7 +1251,7 @@ public virtual Task Include_collection_with_conditional_order_by(bool async) public virtual async Task Include_specified_on_non_entity_not_supported(bool async) { Assert.Equal( - CoreStrings.IncludeOnNonEntity, + CoreStrings.IncludeOnNonEntity("t => t.Item1.Orders"), (await Assert.ThrowsAsync( () => AssertQuery( async, diff --git a/test/EFCore.Specification.Tests/Query/NorthwindStringIncludeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindStringIncludeQueryTestBase.cs index 9a4e2ddd7e3..b4cf574f5bd 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindStringIncludeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindStringIncludeQueryTestBase.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.TestModels.Northwind; @@ -151,6 +152,16 @@ var orders public override Task Filtered_include_with_multiple_ordering(bool async) => Task.CompletedTask; + public override async Task Include_specified_on_non_entity_not_supported(bool async) + { + Assert.Equal( + CoreStrings.IncludeOnNonEntity("\"Item1.Orders\""), + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Select(c => new Tuple(c, 5)).Include(t => t.Item1.Orders)))).Message); + } + protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression) { serverQueryExpression = base.RewriteServerQueryExpression(serverQueryExpression); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs index 1c6e930a069..b77875e66d4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs @@ -1437,7 +1437,7 @@ public override async Task Projecting_after_navigation_and_distinct_throws(bool public override Task Reverse_without_explicit_ordering_throws(bool async) { return AssertTranslationFailedWithDetails( - () => base.Reverse_without_explicit_ordering_throws(async), RelationalStrings.MissingOrderingInSqlExpression); + () => base.Reverse_without_explicit_ordering_throws(async), RelationalStrings.MissingOrderingInSelectExpression); } public override async Task Custom_projection_reference_navigation_PK_to_FK_optimization(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs index 65b04fbd096..93ad0dae8bc 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; @@ -38,7 +39,7 @@ var customers "Compiling query expression: ", Fixture.TestSqlLoggerFactory.Log[0].Message); Assert.StartsWith( - "queryContext => new SingleQueryingEnumerable(", + "Generated query execution expression: " + Environment.NewLine + "'queryContext => new SingleQueryingEnumerable(", Fixture.TestSqlLoggerFactory.Log[1].Message); } @@ -52,7 +53,7 @@ var customers Assert.NotNull(customers); Assert.StartsWith( - "queryContext => new SplitQueryingEnumerable(", + "Generated query execution expression: " + Environment.NewLine + "'queryContext => new SplitQueryingEnumerable(", Fixture.TestSqlLoggerFactory.Log[1].Message); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs index 4a4cb3d04b3..440886500dd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs @@ -218,7 +218,7 @@ public override Task SelectMany_with_collection_being_correlated_subquery_which_ public override Task Reverse_without_explicit_ordering_throws(bool async) { return AssertTranslationFailedWithDetails( - () => base.Reverse_without_explicit_ordering_throws(async), RelationalStrings.MissingOrderingInSqlExpression); + () => base.Reverse_without_explicit_ordering_throws(async), RelationalStrings.MissingOrderingInSelectExpression); } private void AssertSql(params string[] expected) diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs index 6be4947734a..45ab5962771 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/SqliteDatabaseModelFactoryTest.cs @@ -966,7 +966,7 @@ CONSTRAINT MYFK FOREIGN KEY (ForeignKeyId) REFERENCES PrincipalTable(Id) ON DELE .EventId, Id); Assert.Equal( SqliteResources.LogForeignKeyScaffoldErrorPrincipalTableNotFound(new TestLogger()) - .GenerateMessage("0"), Message); + .GenerateMessage("0", "DependentTable", "PrincipalTable"), Message); }, @" DROP TABLE DependentTable;