Skip to content

SqlException : Parameter Naming Conflict (.Net10) #839

@JBWereRuss

Description

@JBWereRuss

Summary

When using the Future Query pattern with variables that have identical names but different casing (e.g. keyword and KEYWORD), Z.EntityFramework.Plus generates conflicting SQL parameter names, resulting in a SqlException about duplicate and missing variable declarations.

This may be related to this bug in EF Core 10 which has now been fixed.

Environment

Z.EntityFramework.Plus Version: 10.105.2.1
• Entity Framework Core Version: 10.0.2

Minimal Reproduction

using Microsoft.EntityFrameworkCore;
using Z.EntityFramework.Plus;

record Document(string Name)
{
    public int Id { get; init; }
}

class AppDbContext : DbContext
{
    public DbSet<Document> Documents { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Database=DocumentDb;Trusted_Connection=true;TrustServerCertificate=true;");
    }
}

class Program
{
    static async Task Main()
    {
        // Populate SQL Server database
        await using var context = new AppDbContext();
        await context.Database.EnsureDeletedAsync();
        await context.Database.EnsureCreatedAsync();

        context.Documents.AddRange([
            new("Annual Report 2024"),
            new("Marketing Strategy"),
            new("Technical Specification")
        ]);

        await context.SaveChangesAsync();

        var keyword = "Annual";
        var KEYWORD = "Annual";

        var query = context.Documents
            .AsNoTracking()
            .Where(d => d.Name.Contains(keyword) || d.Name.Contains(KEYWORD));

        var totalCount = query
            .DeferredCount()
            .FutureValue();

        _ = await query
            .Future()
            .ToListAsync();
    }
}

Generated SQL

exec sp_executesql N'-- EF+ Query Future: 1 of 2
SELECT COUNT(*)
FROM [Documents] AS [d]
WHERE [d].[Name] LIKE @Z_1_keyword_contains ESCAPE N''\'' OR [d].[Name] LIKE @Z_1_KEYWORD_contains0 ESCAPE N''\''
;

-- EF+ Query Future: 2 of 2
SELECT [d].[Id], [d].[Name]
FROM [Documents] AS [d]
WHERE [d].[Name] LIKE @Z_2_keyword_contains ESCAPE N''\'' OR [d].[Name] LIKE @Z_2_KEYWORD_contains0 ESCAPE N''\''
;

',N'@Z_1_keyword_contains nvarchar(8),@Z_1_KEYWORD_contains nvarchar(8),@Z_2_keyword_contains nvarchar(8),@Z_2_KEYWORD_contains nvarchar(8)',@Z_1_keyword_contains=N'%Annual%',@Z_1_KEYWORD_contains=N'%Annual%',@Z_2_keyword_contains=N'%Annual%',@Z_2_KEYWORD_contains=N'%Annual%'

Note: in the generated output above, the uppercase variant in the SQL is suffixed with 0 @Z_1_KEYWORD_contains0 but the actual parameter is not @Z_1_KEYWORD_contains.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions