Configured DbFunctionParameter doesn't impact query parameter mapping

Open
#25,980 3 comments 2 reactions 1 assignee View on GitHub

@AndriySvyryd is already working on this.

Since Sep 14, 2021.

Assessment

This issue has not been assessed yet.

Description

area-model-building needs-design

When configuring a function's parameter's mapping in the model:

modelBuilder.HasDbFunction(...).HasParameter("startDate").Metadata.TypeMapping
    = typeMappingSource.GetMapping("...");

My expectation was that this would impact the mapping used in the query pipeline (i.e. when a constant/parameter is given), but that does not seem to be the case.

Repro
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();

await ctx.Database.ExecuteSqlRawAsync(@"
CREATE FUNCTION Foo(@p bit)
RETURNS int
AS
BEGIN
    RETURN 0;
END");

_ = await ctx.Blogs.Where(b => ctx.Foo("true") == 0).ToListAsync();

public class BlogContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    static ILoggerFactory ContextLoggerFactory
        => LoggerFactory.Create(b => b.AddConsole().AddFilter("", LogLevel.Information));

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0")
            .EnableSensitiveDataLogging()
            .UseLoggerFactory(ContextLoggerFactory);

    public int Foo(object p) => throw new NotSupportedException();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var typeMappingSource = this.GetService<IRelationalTypeMappingSource>();

        modelBuilder.HasDbFunction(typeof(BlogContext).GetMethod(nameof(Foo))!)
                .HasParameter("p")
                .Metadata.TypeMapping = typeMappingSource.GetMapping(typeof(bool));
    }
}

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
}

The above generates the SQL [dbo].[Foo](N'true'), whereas I'd expect it to generate [dbo].[Foo](CAST(1 AS bit)) (or possibly throw).

Dominant language
C#
Stars
14.8k
Forks
3.4k
Avg merge
2d 5h
Merged PRs (30d)
134

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/efcore

All issues in dotnet/efcore

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.