Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamicParameters.Add cannot 'override' the property of template if value is DbString #731

Closed
jiabiao opened this issue Mar 25, 2017 · 1 comment · Fixed by #782
Closed

Comments

@jiabiao
Copy link

jiabiao commented Mar 25, 2017

I am using an object as parameters template, and use the DynamicParameters.Add method to 'override' a string property to DbString so that it can use SQL Server index.
But i got the exception : The variable name has already been declared.

        public static void Run()
        {
            Test(1);  //ok
            Test("1"); //ok
            Test(DateTime.Now); //ok
            Test(new DbString() { Value = "1" });  //System.Data.SqlClient.SqlException: 'The variable name '@Value' has already been declared.
        }

        public static void Test<T>(T value)
        {
            using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=master;Persist Security Info=True;"))
            {
                var template = new { Value = value };
                var dp = new DynamicParameters(template);
                dp.Add("Value", value);
                conn.Execute("SELECT 1 WHERE @Value IS NOT NULL", dp);  
            }
        }
@jiabiao
Copy link
Author

jiabiao commented Apr 5, 2017

Not only DbString, any type implement SqlMapper.ICustomQueryParameter have this issue.

For other types(does not ICustomQueryParameter), there are some code to prevent dupilcate parameters, so there are no problem.
DynamicParameters.AddParameters code:

if (isCustomQueryParameter)
{
// DbString goes to here.
}
else
{
                    bool add = !command.Parameters.Contains(name);
                    IDbDataParameter p;
                    if (add)
                    {
                        p = command.CreateParameter();
                        p.ParameterName = name;
                    }
                    else
                    {
                        p = (IDbDataParameter)command.Parameters[name];
                    }
}

so ICustomQueryParameter will be appended to command twice:

  1. IL DynamicMethod: appender(command, template);
  2. SqlMapper.ICustomQueryParameter.AddParameter(command, name)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant