diff --git a/src/EFCore.Relational/Query/Pipeline/ISqlExpressionFactory.cs b/src/EFCore.Relational/Query/Pipeline/ISqlExpressionFactory.cs index 8eaeee3b3d4..6666ac27cff 100644 --- a/src/EFCore.Relational/Query/Pipeline/ISqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/Pipeline/ISqlExpressionFactory.cs @@ -16,6 +16,7 @@ public interface ISqlExpressionFactory SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping); SqlExpression ApplyDefaultTypeMapping(SqlExpression sqlExpression); RelationalTypeMapping GetTypeMappingForValue(object value); + RelationalTypeMapping FindMapping(Type type); #endregion #region Binary diff --git a/src/EFCore.Relational/Query/Pipeline/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/Pipeline/RelationalSqlTranslatingExpressionVisitor.cs index 57a003d6d98..eeb5ad6434b 100644 --- a/src/EFCore.Relational/Query/Pipeline/RelationalSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/Pipeline/RelationalSqlTranslatingExpressionVisitor.cs @@ -2,10 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Runtime.InteropServices.ComTypes; using Microsoft.EntityFrameworkCore.Extensions.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -209,10 +211,43 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp return _methodCallTranslatorProvider.Translate(_model, (SqlExpression)@object, methodCallExpression.Method, arguments); } + private static Expression TryRemoveImplicitConvert(Expression expression) + { + if (expression is UnaryExpression unaryExpression) + { + if (unaryExpression.NodeType == ExpressionType.Convert + || unaryExpression.NodeType == ExpressionType.ConvertChecked) + { + var innerType = unaryExpression.Operand.Type.UnwrapNullableType(); + if (innerType.IsEnum) + { + innerType = Enum.GetUnderlyingType(innerType); + } + var convertedType = unaryExpression.Type.UnwrapNullableType(); + + if (innerType == convertedType + || (convertedType == typeof(int) + && (innerType == typeof(byte) + || innerType == typeof(sbyte) + || innerType == typeof(char) + || innerType == typeof(short) + || innerType == typeof(ushort)))) + { + return TryRemoveImplicitConvert(unaryExpression.Operand); + } + } + } + + return expression; + } + protected override Expression VisitBinary(BinaryExpression binaryExpression) { - var left = Visit(binaryExpression.Left); - var right = Visit(binaryExpression.Right); + var left = TryRemoveImplicitConvert(binaryExpression.Left); + var right = TryRemoveImplicitConvert(binaryExpression.Right); + + left = Visit(left); + right = Visit(right); if (TranslationFailed(binaryExpression.Left, left) || TranslationFailed(binaryExpression.Right, right)) @@ -331,9 +366,17 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression) { return sqlOperand; } - sqlOperand = _sqlExpressionFactory.ApplyDefaultTypeMapping(sqlOperand); - return _sqlExpressionFactory.Convert(sqlOperand, unaryExpression.Type); + // Introduce explicit cast only if the target type is mapped else we need to client eval + if (unaryExpression.Type == typeof(object) + || _sqlExpressionFactory.FindMapping(unaryExpression.Type) != null) + { + sqlOperand = _sqlExpressionFactory.ApplyDefaultTypeMapping(sqlOperand); + + return _sqlExpressionFactory.Convert(sqlOperand, unaryExpression.Type); + } + + break; } return null; diff --git a/src/EFCore.Relational/Query/Pipeline/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/Pipeline/SqlExpressionFactory.cs index 38cb91f3e8c..27c98e91117 100644 --- a/src/EFCore.Relational/Query/Pipeline/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/Pipeline/SqlExpressionFactory.cs @@ -205,6 +205,11 @@ public virtual RelationalTypeMapping GetTypeMappingForValue(object value) { return _typeMappingSource.GetMappingForValue(value); } + + public virtual RelationalTypeMapping FindMapping(Type type) + { + return _typeMappingSource.FindMapping(type); + } #endregion #region Binary diff --git a/src/EFCore.Relational/Storage/RelationalTypeMapping.cs b/src/EFCore.Relational/Storage/RelationalTypeMapping.cs index 50d24b39011..96381806e98 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMapping.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMapping.cs @@ -500,6 +500,12 @@ public virtual string GenerateSqlLiteral([CanBeNull] object value) { if (Converter != null) { + if (value?.GetType().IsInteger() == true + && ClrType.UnwrapNullableType().IsEnum) + { + value = Enum.ToObject(ClrType.UnwrapNullableType(), value); + } + value = Converter.ConvertToProvider(value); } diff --git a/src/EFCore/Query/Pipeline/ParameterExtractingExpressionVisitor.cs b/src/EFCore/Query/Pipeline/ParameterExtractingExpressionVisitor.cs index 1bdbcead39a..eaedc6b022f 100644 --- a/src/EFCore/Query/Pipeline/ParameterExtractingExpressionVisitor.cs +++ b/src/EFCore/Query/Pipeline/ParameterExtractingExpressionVisitor.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -31,7 +32,6 @@ public class ParameterExtractingExpressionVisitor : ExpressionVisitor private readonly bool _generateContextAccessors; private readonly EvaluatableExpressionFindingExpressionVisitor _evaluatableExpressionFindingExpressionVisitor; private readonly ContextParameterReplacingExpressionVisitor _contextParameterReplacingExpressionVisitor; - private readonly Dictionary _evaluatedValues = new Dictionary(ExpressionEqualityComparer.Instance); @@ -122,15 +122,19 @@ protected virtual bool PreserveConvertNode(Expression expression) || unaryExpression.NodeType == ExpressionType.ConvertChecked)) { if (unaryExpression.Type == typeof(object) - || unaryExpression.Type == typeof(Enum)) + || unaryExpression.Type == typeof(Enum) + || unaryExpression.Operand.Type.UnwrapNullableType().IsEnum) { return true; } + var innerType = unaryExpression.Operand.Type.UnwrapNullableType(); if (unaryExpression.Type.UnwrapNullableType() == typeof(int) - && (unaryExpression.Operand.Type.UnwrapNullableType().IsEnum - || unaryExpression.Operand.Type.UnwrapNullableType() == typeof(char) - || unaryExpression.Operand.Type.UnwrapNullableType() == typeof(ushort))) + && (innerType == typeof(byte) + || innerType == typeof(sbyte) + || innerType == typeof(char) + || innerType == typeof(short) + || innerType == typeof(ushort))) { return true; } diff --git a/test/EFCore.Cosmos.FunctionalTests/BuiltInDataTypesCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/BuiltInDataTypesCosmosTest.cs index 9264934661a..78a89038ffc 100644 --- a/test/EFCore.Cosmos.FunctionalTests/BuiltInDataTypesCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/BuiltInDataTypesCosmosTest.cs @@ -45,6 +45,8 @@ public class BuiltInDataTypesCosmosFixture : BuiltInDataTypesFixtureBase public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) diff --git a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs index 15c38c6df67..dd4926f2cc7 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs @@ -49,6 +49,8 @@ public class CustomConvertersCosmosFixture : CustomConvertersFixtureBase public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) diff --git a/test/EFCore.InMemory.FunctionalTests/BuiltInDataTypesInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/BuiltInDataTypesInMemoryTest.cs index e241cede30b..ee96addf5ac 100644 --- a/test/EFCore.InMemory.FunctionalTests/BuiltInDataTypesInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/BuiltInDataTypesInMemoryTest.cs @@ -3,6 +3,7 @@ using System; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore @@ -14,6 +15,12 @@ public BuiltInDataTypesInMemoryTest(BuiltInDataTypesInMemoryFixture fixture) { } + [ConditionalFact(Skip = "Issue#15711")] + public override void Can_insert_and_read_back_with_string_key() + { + base.Can_insert_and_read_back_with_string_key(); + } + public class BuiltInDataTypesInMemoryFixture : BuiltInDataTypesFixtureBase { protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance; @@ -28,6 +35,8 @@ public class BuiltInDataTypesInMemoryFixture : BuiltInDataTypesFixtureBase public override bool SupportsBinaryKeys => false; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); } } diff --git a/test/EFCore.InMemory.FunctionalTests/ConvertToProviderTypesInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/ConvertToProviderTypesInMemoryTest.cs index c52d497f145..4fa04a7fc8c 100644 --- a/test/EFCore.InMemory.FunctionalTests/ConvertToProviderTypesInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ConvertToProviderTypesInMemoryTest.cs @@ -3,6 +3,7 @@ using System; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; namespace Microsoft.EntityFrameworkCore { @@ -14,6 +15,12 @@ public ConvertToProviderTypesInMemoryTest(ConvertToProviderTypesInMemoryFixture { } + [ConditionalFact(Skip = "Issue#15711")] + public override void Can_insert_and_read_back_with_string_key() + { + base.Can_insert_and_read_back_with_string_key(); + } + public class ConvertToProviderTypesInMemoryFixture : ConvertToProviderTypesFixtureBase { protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance; @@ -28,6 +35,8 @@ public class ConvertToProviderTypesInMemoryFixture : ConvertToProviderTypesFixtu public override bool SupportsBinaryKeys => false; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); } } diff --git a/test/EFCore.InMemory.FunctionalTests/CustomConvertersInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/CustomConvertersInMemoryTest.cs index 72fb90a9a19..984c89c50cd 100644 --- a/test/EFCore.InMemory.FunctionalTests/CustomConvertersInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/CustomConvertersInMemoryTest.cs @@ -3,6 +3,7 @@ using System; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; namespace Microsoft.EntityFrameworkCore { @@ -18,6 +19,12 @@ public override void Can_insert_and_read_back_with_case_insensitive_string_key() { } + [ConditionalFact(Skip = "Issue#15711")] + public override void Can_insert_and_read_back_with_string_key() + { + base.Can_insert_and_read_back_with_string_key(); + } + public class CustomConvertersInMemoryFixture : CustomConvertersFixtureBase { public override bool StrictEquality => true; @@ -32,6 +39,8 @@ public class CustomConvertersInMemoryFixture : CustomConvertersFixtureBase public override bool SupportsBinaryKeys => false; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); } } diff --git a/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs b/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs index 441efab3fae..3bec043684c 100644 --- a/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs +++ b/test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs @@ -52,7 +52,7 @@ public virtual async Task Can_filter_projection_with_captured_enum_variable(bool } } - [Theory(Skip = "QueryIssue")] + [Theory] [InlineData(false)] [InlineData(true)] public virtual async Task Can_filter_projection_with_inline_enum_variable(bool async) @@ -202,7 +202,7 @@ public virtual void Can_perform_query_with_ansi_strings_test() } } - [Fact(Skip = "QueryIssue")] + [Fact] public virtual void Can_query_using_any_data_type() { using (var context = CreateContext()) @@ -215,7 +215,7 @@ public virtual void Can_query_using_any_data_type() } } - [Fact(Skip = "QueryIssue")] + [Fact] public virtual void Can_query_using_any_data_type_shadow() { using (var context = CreateContext()) @@ -260,7 +260,7 @@ private void QueryBuiltInDataTypesTest(EntityEntry source) e => e.Id == 11 && EF.Property(e, nameof(BuiltInDataTypes.TestDouble)) == param4).ToList().Single()); } - else + else if (Fixture.SupportsDecimalComparisons) { double? param4l = -1.234567891; double? param4h = -1.234567889; @@ -311,7 +311,7 @@ private void QueryBuiltInDataTypesTest(EntityEntry source) e => e.Id == 11 && EF.Property(e, nameof(BuiltInDataTypes.TestSingle)) == param9).ToList().Single()); } - else + else if (Fixture.SupportsDecimalComparisons) { var param9l = -1.2341F; var param9h = -1.2339F; @@ -548,7 +548,7 @@ protected EntityEntry AddTestBuiltInDataTypes(DbSet s return entityEntry; } - [Fact(Skip = "QueryIssue")] + [Fact] public virtual void Can_query_using_any_nullable_data_type() { using (var context = CreateContext()) @@ -561,7 +561,7 @@ public virtual void Can_query_using_any_nullable_data_type() } } - [Fact(Skip = "QueryIssue")] + [Fact] public virtual void Can_query_using_any_data_type_nullable_shadow() { using (var context = CreateContext()) @@ -610,7 +610,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou && EF.Property(e, nameof(BuiltInNullableDataTypes.TestNullableDouble)) == param4).ToList() .Single()); } - else + else if (Fixture.SupportsDecimalComparisons) { double? param4l = -1.234567891; double? param4h = -1.234567889; @@ -665,7 +665,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou && EF.Property(e, nameof(BuiltInNullableDataTypes.TestNullableSingle)) == param9).ToList() .Single()); } - else + else if (Fixture.SupportsDecimalComparisons) { float? param9l = -1.2341F; float? param9h = -1.2339F; @@ -696,19 +696,19 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou Enum64? param12 = Enum64.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum64)) == param12).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum64)) == param12).ToList() .Single()); Enum32? param13 = Enum32.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum32)) == param13).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum32)) == param13).ToList() .Single()); Enum16? param14 = Enum16.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum16)) == param14).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum16)) == param14).ToList() .Single()); if (entityType.FindProperty(nameof(BuiltInNullableDataTypes.Enum8)) != null) @@ -716,7 +716,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou Enum8? param15 = Enum8.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum8)) == param15).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.Enum8)) == param15).ToList() .Single()); } @@ -777,7 +777,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou var param21 = EnumU64.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU64)) == param21).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU64)) == param21).ToList() .Single()); } @@ -786,7 +786,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou var param22 = EnumU32.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU32)) == param22).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU32)) == param22).ToList() .Single()); } @@ -795,7 +795,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou var param23 = EnumU16.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU16)) == param23).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumU16)) == param23).ToList() .Single()); } @@ -804,7 +804,7 @@ private void QueryBuiltInNullableDataTypesTest(EntityEntry sou var param24 = EnumS8.SomeValue; Assert.Same( entity, - set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumS8)) == param24).ToList() + set.Where(e => e.Id == 11 && EF.Property(e, nameof(BuiltInNullableDataTypes.EnumS8)) == param24).ToList() .Single()); } @@ -924,7 +924,7 @@ protected virtual EntityEntry AddTestBuiltInNullableDataTypes( return entityEntry; } - [Fact(Skip = "QueryIssue")] + [Fact] public virtual void Can_query_using_any_nullable_data_type_as_literal() { using (var context = CreateContext()) @@ -981,15 +981,22 @@ public virtual void Can_query_using_any_nullable_data_type_as_literal() context.Set().Where(e => e.Id == 12 && e.TestNullableInt64 == -1234567890123456789L).ToList() .Single()); - Assert.Same( - entity, - Fixture.StrictEquality - ? context.Set().Where(e => e.Id == 12 && e.TestNullableDouble == -1.23456789).ToList() - .Single() - : context.Set().Where( + if (Fixture.StrictEquality) + { + Assert.Same( + entity, + context.Set().Where(e => e.Id == 12 && e.TestNullableDouble == -1.23456789).ToList() + .Single()); + } + else if (Fixture.SupportsDecimalComparisons) + { + Assert.Same( + entity, + context.Set().Where( e => e.Id == 12 - && -e.TestNullableDouble + -1.23456789 < 1E-5 - && -e.TestNullableDouble + -1.23456789 > -1E-5).ToList().Single()); + && -e.TestNullableDouble + -1.23456789 < 1E-5 + && -e.TestNullableDouble + -1.23456789 > -1E-5).ToList().Single()); + } Assert.Same( entity, @@ -1023,13 +1030,20 @@ public virtual void Can_query_using_any_nullable_data_type_as_literal() .Where(e => e.Id == 12 && e.TestNullableTimeSpan == new TimeSpan(0, 10, 9, 8, 7)).ToList().Single()); } - Assert.Same( - entity, - Fixture.StrictEquality - ? context.Set().Where(e => e.Id == 12 && e.TestNullableSingle == -1.234F).ToList() - .Single() - : context.Set().Where(e => e.Id == 12 && -e.TestNullableSingle + -1.234F < 1E-5).ToList() + if (Fixture.StrictEquality) + { + Assert.Same( + entity, + context.Set().Where(e => e.Id == 12 && e.TestNullableSingle == -1.234F).ToList() .Single()); + } + else if (Fixture.SupportsDecimalComparisons) + { + Assert.Same( + entity, + context.Set().Where(e => e.Id == 12 && -e.TestNullableSingle + -1.234F < 1E-5).ToList() + .Single()); + } Assert.Same( entity, @@ -1134,7 +1148,7 @@ public virtual void Can_query_using_any_nullable_data_type_as_literal() } } - [Fact(Skip = "Tasklist#8")] + [Fact] public virtual void Can_query_with_null_parameters_using_any_nullable_data_type() { using (var context = CreateContext()) @@ -1416,7 +1430,7 @@ public virtual void Can_insert_and_read_with_max_length_set() } } - [Fact(Skip = "Tasklist#19")] + [Fact] public virtual void Can_insert_and_read_back_with_binary_key() { if (!Fixture.SupportsBinaryKeys) @@ -1477,7 +1491,7 @@ public virtual void Can_insert_and_read_back_with_null_binary_foreign_key() } } - [Fact(Skip = "Tasklist#19")] + [Fact] public virtual void Can_insert_and_read_back_with_string_key() { using (var context = CreateContext()) @@ -1826,6 +1840,8 @@ protected static void MakeRequired(ModelBuilder modelBuilder) public abstract bool SupportsBinaryKeys { get; } + public abstract bool SupportsDecimalComparisons { get; } + public abstract DateTime DefaultDateTime { get; } } diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index f4d48456f95..fe2d55210fd 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -699,9 +699,10 @@ await AssertQuery( isAsync, gs => gs.Where(g => ((short)g.Rank & (short)1) == 1)); - await AssertQuery( - isAsync, - gs => gs.Where(g => ((char)g.Rank & '\x0001') == '\x0001')); + // Issue#15950 + //await AssertQuery( + // isAsync, + // gs => gs.Where(g => ((char)g.Rank & '\x0001') == '\x0001')); } [ConditionalTheory] diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs index 33513d43adb..26b45f1513b 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs @@ -465,7 +465,7 @@ public string GetCity() } } - [ConditionalTheory(Skip = "TaskList#8")] + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Where_simple_closure_via_query_cache_nullable_type(bool isAsync) { @@ -491,7 +491,7 @@ await AssertQuery( entryCount: 1); } - [ConditionalTheory(Skip = "TaskList#8")] + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Where_simple_closure_via_query_cache_nullable_type_reverse(bool isAsync) { @@ -809,7 +809,7 @@ await AssertQuery( entryCount: 5); } - [ConditionalTheory(Skip = "TaskList#8")] + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Where_equals_on_null_nullable_int_types(bool isAsync) { diff --git a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs index c45952d7232..e8da109c61e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs @@ -412,12 +412,11 @@ public virtual void Can_query_using_any_mapped_data_type() ulong? param42 = ulong.MaxValue; Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.UlongAsBigint == param42)); - // TODO: Issue#15330 - //ushort? param43 = ushort.MaxValue; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.UShortAsSmallint == param43)); + ushort? param43 = ushort.MaxValue; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.UShortAsSmallint == param43)); - //sbyte? param44 = sbyte.MinValue; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.SbyteAsTinyint == param44)); + sbyte? param44 = sbyte.MinValue; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.SbyteAsTinyint == param44)); uint? param45 = uint.MaxValue; Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.UintAsBigint == param45)); @@ -435,37 +434,37 @@ public virtual void Can_query_using_any_mapped_data_type() Assert.Same( entity, context.Set().Single(e => e.Int == 999 && e.GuidAsUniqueidentifier == param49)); - //char? param50 = 'A'; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsVarcharMax == param50)); + char? param50 = 'A'; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsVarcharMax == param50)); - //char? param51 = 'B'; - //Assert.Same( - // entity, context.Set().Single(e => e.Int == 999 && e.CharAsAsCharVaryingMax == param51)); + char? param51 = 'B'; + Assert.Same( + entity, context.Set().Single(e => e.Int == 999 && e.CharAsAsCharVaryingMax == param51)); - //char? param52 = 'C'; - //Assert.Same( - // entity, context.Set().Single(e => e.Int == 999 && e.CharAsCharacterVaryingMax == param52)); + char? param52 = 'C'; + Assert.Same( + entity, context.Set().Single(e => e.Int == 999 && e.CharAsCharacterVaryingMax == param52)); - //char? param53 = 'D'; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsNvarcharMax == param53)); + char? param53 = 'D'; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsNvarcharMax == param53)); - //char? param54 = 'E'; - //Assert.Same( - // entity, context.Set().Single(e => e.Int == 999 && e.CharAsNationalCharVaryingMax == param54)); + char? param54 = 'E'; + Assert.Same( + entity, context.Set().Single(e => e.Int == 999 && e.CharAsNationalCharVaryingMax == param54)); - //char? param55 = 'F'; - //Assert.Same( - // entity, - // context.Set().Single(e => e.Int == 999 && e.CharAsNationalCharacterVaryingMax == param55)); + char? param55 = 'F'; + Assert.Same( + entity, + context.Set().Single(e => e.Int == 999 && e.CharAsNationalCharacterVaryingMax == param55)); - //char? param58 = 'I'; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsInt == param58)); + char? param58 = 'I'; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.CharAsInt == param58)); - //StringEnumU16? param59 = StringEnumU16.Value4; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.EnumAsNvarchar20 == param59)); + StringEnumU16? param59 = StringEnumU16.Value4; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.EnumAsNvarchar20 == param59)); - //StringEnum16? param60 = StringEnum16.Value2; - //Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.EnumAsVarcharMax == param60)); + StringEnum16? param60 = StringEnum16.Value2; + Assert.Same(entity, context.Set().Single(e => e.Int == 999 && e.EnumAsVarcharMax == param60)); // Issue #14935. Cannot eval 'where [e].SqlVariantString.Equals(__param61_0)' // Added AsEnumerable() @@ -479,7 +478,7 @@ public virtual void Can_query_using_any_mapped_data_type() } } - [Fact(Skip = "TaskList#8")] + [Fact] public virtual void Can_query_using_any_mapped_data_types_with_nulls() { using (var context = CreateContext()) @@ -571,11 +570,12 @@ public virtual void Can_query_using_any_mapped_data_types_with_nulls() entity, context.Set().Single(e => e.Int == 911 && e.StringAsNationalCharacterVaryingMax == param29)); - string param30 = null; - Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.StringAsText == param30)); + // TODO: See issue#15953 + //string param30 = null; + //Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.StringAsText == param30)); - string param31 = null; - Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.StringAsNtext == param31)); + //string param31 = null; + //Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.StringAsNtext == param31)); byte[] param35 = null; Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.BytesAsVarbinaryMax == param35)); @@ -584,8 +584,8 @@ public virtual void Can_query_using_any_mapped_data_types_with_nulls() Assert.Same( entity, context.Set().Single(e => e.Int == 911 && e.BytesAsBinaryVaryingMax == param36)); - byte[] param37 = null; - Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.BytesAsImage == param37)); + //byte[] param37 = null; + //Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.BytesAsImage == param37)); decimal? param38 = null; Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.Decimal == param38)); @@ -647,11 +647,11 @@ public virtual void Can_query_using_any_mapped_data_types_with_nulls() entity, context.Set().Single(e => e.Int == 911 && e.CharAsNationalCharacterVaryingMax == param55)); - char? param56 = null; - Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.CharAsText == param56)); + //char? param56 = null; + //Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.CharAsText == param56)); - char? param57 = null; - Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.CharAsNtext == param57)); + //char? param57 = null; + //Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.CharAsNtext == param57)); char? param58 = null; Assert.Same(entity, context.Set().Single(e => e.Int == 911 && e.CharAsInt == param58)); @@ -3041,6 +3041,8 @@ public class BuiltInDataTypesSqlServerFixture : BuiltInDataTypesFixtureBase public override bool SupportsLargeStringComparisons => true; + public override bool SupportsDecimalComparisons => true; + protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; diff --git a/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs index 5d5e8696cdf..68e1e7e0cde 100644 --- a/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/ConvertToProviderTypesSqlServerTest.cs @@ -190,6 +190,8 @@ public class ConvertToProviderTypesSqlServerFixture : ConvertToProviderTypesFixt public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs index 6aeec85c6f6..959fb6f64e9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/CustomConvertersSqlServerTest.cs @@ -181,6 +181,8 @@ public class CustomConvertersSqlServerFixture : CustomConvertersFixtureBase public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs index fd529d2bf05..2adce5eb3d8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/EverythingIsBytesSqlServerTest.cs @@ -175,6 +175,8 @@ public class EverythingIsBytesSqlServerFixture : BuiltInDataTypesFixtureBase public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs index 222b5a2e548..668bb1b3a03 100644 --- a/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/EverythingIsStringsSqlServerTest.cs @@ -176,6 +176,8 @@ public class EverythingIsStringsSqlServerFixture : BuiltInDataTypesFixtureBase public override bool SupportsBinaryKeys => true; + public override bool SupportsDecimalComparisons => true; + public override DateTime DefaultDateTime => new DateTime(); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) diff --git a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs index 01b2deb335f..6f16d8d243a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs @@ -1519,6 +1519,8 @@ public class BuiltInDataTypesSqliteFixture : BuiltInDataTypesFixtureBase public override bool SupportsLargeStringComparisons => true; + public override bool SupportsDecimalComparisons => false; + protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; diff --git a/test/EFCore.Sqlite.FunctionalTests/ConvertToProviderTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/ConvertToProviderTypesSqliteTest.cs index cff6856d8fb..e3dec54f1fd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ConvertToProviderTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ConvertToProviderTypesSqliteTest.cs @@ -28,6 +28,8 @@ public class ConvertToProviderTypesSqliteFixture : ConvertToProviderTypesFixture public override bool SupportsLargeStringComparisons => true; + public override bool SupportsDecimalComparisons => false; + protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory; diff --git a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs index 0bb51a6ec12..6983e82d949 100644 --- a/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/CustomConvertersSqliteTest.cs @@ -29,6 +29,8 @@ public class CustomConvertersSqliteFixture : CustomConvertersFixtureBase public override bool SupportsLargeStringComparisons => true; + public override bool SupportsDecimalComparisons => false; + protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory;