We use Oracle as our database provider and have looked into replacing some of our data access layer (hard to maintain, harder to merge XSD\'s) with a saner repository based
Resolution of the named parameter issue turned out to be because Oracle commands require the BindByName property set to true. To resolve this required a tweak to the SqlMapper itself. This is a bit nasty as the tweak isnt portable (it relies on a type check for a specific Oracle Command) but it works for our needs for the moment. The change involves updating the SetupCommand method, after creating the command form the connection object we type check and set the flag like so (~ln 635):
var cmd = cnn.CreateCommand();
if (cmd is OracleCommand)
{
((OracleCommand)cmd).BindByName = true; // Oracle Command Only
}
Finally to address the issue of the "@" to ":" problem in parameter names involved altering the CreateParamInfoGenerator method. I added a static string - DefaultParameterCharacter setting its value to ":" then modified ln 530 from:
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [c
to
il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [command] [name] (Changed @ to : for oracle)
and ln 546 from:
il.Emit(OpCodes.Ldstr, "@" + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)
to:
il.Emit(OpCodes.Ldstr, DefaultParameterCharacter + prop.Name); // stack is now [parameters] [parameters] [parameter] [parameter] [name] (Changed @ to : for oracle)
This made dapper work flawlessly with Oracle commands
IMO, the correct approach here is not to (as per the accepted answer) use the database specific parameter prefix (so @
for sql-server, :
for oracle) - but rather: use no prefix at all. So ultimately this is:
il.Emit(OpCodes.Ldstr, prop.Name);
(etc)
In particular, a static
property would be bad as it would limit you to one vendor per AppDomain
.
Dapper has been updated with this change. It also now dynamically detects BindByName
and sets it accordingly (all without needing a reference to OracleCommand
).