From 03ef1867cd4eb353f1a7254696a8d203d23ff03b Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Wed, 2 Nov 2022 02:47:13 -0700 Subject: [PATCH] [release/6.0] Query: Use type mapping from IDbFunction while translating (#27995) (#29216) --- .../RelationalMethodCallTranslatorProvider.cs | 6 ++- .../Query/SimpleQueryRelationalTestBase.cs | 51 +++++++++++++++++++ .../Query/SimpleQuerySqlServerTest.cs | 18 +++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/EFCore.Relational/Query/RelationalMethodCallTranslatorProvider.cs b/src/EFCore.Relational/Query/RelationalMethodCallTranslatorProvider.cs index 1239e3e163b..b2fd5d7ad2e 100644 --- a/src/EFCore.Relational/Query/RelationalMethodCallTranslatorProvider.cs +++ b/src/EFCore.Relational/Query/RelationalMethodCallTranslatorProvider.cs @@ -99,14 +99,16 @@ public RelationalMethodCallTranslatorProvider(RelationalMethodCallTranslatorProv arguments, dbFunction.IsNullable, argumentsPropagateNullability, - method.ReturnType.UnwrapNullableType()) + method.ReturnType.UnwrapNullableType(), + dbFunction.TypeMapping) : _sqlExpressionFactory.Function( dbFunction.Schema, dbFunction.Name, arguments, dbFunction.IsNullable, argumentsPropagateNullability, - method.ReturnType.UnwrapNullableType()); + method.ReturnType.UnwrapNullableType(), + dbFunction.TypeMapping); } return _plugins.Concat(_translators) diff --git a/test/EFCore.Relational.Specification.Tests/Query/SimpleQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/SimpleQueryRelationalTestBase.cs index 97f0f8ab52c..db430eb049c 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/SimpleQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/SimpleQueryRelationalTestBase.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -51,6 +52,56 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) mb.ToTable((string)null); } } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task StoreType_for_UDF_used(bool async) + { + var contextFactory = await InitializeAsync(); + using var context = contextFactory.CreateContext(); + + var date = new DateTime(2012, 12, 12); + var query1 = context.Set().Where(x => x.SomeDate == date); + var query2 = context.Set().Where(x => MyEntity.Modify(x.SomeDate) == date); + + if (async) + { + await query1.ToListAsync(); + await Assert.ThrowsAnyAsync(() => query2.ToListAsync()); + } + else + { + query1.ToList(); + Assert.ThrowsAny(() => query2.ToList()); + } + } + + protected class Context27954 : DbContext + { + public Context27954(DbContextOptions options) + : base(options) + { + } + + public DbSet MyEntities { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder + .HasDbFunction(typeof(MyEntity).GetMethod(nameof(MyEntity.Modify))) + .HasName("ModifyDate") + .HasStoreType("datetime") + .HasSchema("dbo"); + } + } + + protected class MyEntity + { + public int Id { get; set; } + [Column(TypeName = "datetime")] + public DateTime SomeDate { get; set; } + public static DateTime Modify(DateTime date) => throw new NotSupportedException(); + } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs index bd57fdb0ba8..79abafd11b0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.cs @@ -321,6 +321,24 @@ HAVING COUNT(*) = 1 ORDER BY [t].[ParcelNumber]"); } + public override async Task StoreType_for_UDF_used(bool async) + { + await base.StoreType_for_UDF_used(async); + + AssertSql( + @"@__date_0='2012-12-12T00:00:00.0000000' (DbType = DateTime) + +SELECT [m].[Id], [m].[SomeDate] +FROM [MyEntities] AS [m] +WHERE [m].[SomeDate] = @__date_0", + // + @"@__date_0='2012-12-12T00:00:00.0000000' (DbType = DateTime) + +SELECT [m].[Id], [m].[SomeDate] +FROM [MyEntities] AS [m] +WHERE [dbo].[ModifyDate]([m].[SomeDate]) = @__date_0"); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Muliple_occurrences_of_FromSql_in_group_by_aggregate(bool async)