Skip to content

Case-sensitive parameter names #18861

@zabolotnev

Description

@zabolotnev

I'm used to all IDbCommand implementations have case insensitive parameter names. This is true for the SqlClient namespace and the System.Data.SQLite package. This feature is very useful, but when I started using the Microsoft.Data.Sqlite package, I got an error:
System.InvalidOperationException: 'Must add values for the following parameters'

To Reproduce

    class TestClass
    {
        public static void Test()
        {
            var f = "testdb.sqlite";
            if (File.Exists(f))
            {
                File.Delete(f);
            }
            using (var conn = new SqliteConnection("Data source = " + f))
            {
                conn.Open();
                var cmd = conn.CreateCommand();
                cmd.CommandText = "Create table test(f1 integer)";
                cmd.ExecuteNonQuery();

                cmd.CommandText = "select * from test where f1 = @PRM";

                var p = cmd.CreateParameter();
                p.ParameterName = "@prm";
                p.Value = 1;
                cmd.Parameters.Add(p);

                using (cmd.ExecuteReader()) { }

            }
        }
    }

Result:

System.InvalidOperationException
  HResult=0x80131509
  Message=Must add values for the following parameters: @PRM
  Source=Microsoft.Data.Sqlite
  StackTrace:
   at Microsoft.Data.Sqlite.SqliteCommand.<GetStatements>d__54.MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader()
   at ConsoleApp14.TestMS.Test() in D:\Projects\ConsoleApp14\TestMS.cs:line 34

Additional context

I found the reason of case-sensitivity here: https://github.com/aspnet/EntityFrameworkCore/blob/master/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
Line 336:

if (_parameters.IsValueCreated
&& !_parameters.Value.Cast<SqliteParameter>().Any(p => p.ParameterName == name))

Equality operator == is case sensitive.

For example, System.Data.SQLite uses this method of compare:
https://github.com/OpenDataSpace/System.Data.SQLite/blob/master/System.Data.SQLite/SQLiteStatement.cs
Line 209:

if (String.Compare(_paramNames[n], startAt, s, 0, Math.Max(_paramNames[n].Length - startAt, s.Length), StringComparison.OrdinalIgnoreCase) == 0)

Microsoft.Data.Sqlite version: 3.1.0-preview2.19525.5
Target framework: .NET 4.8, Xamarin
Operating system: Windows, Android

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions