Getting the content of DynamicParameters in Dapper

c# dapper reflection

Question

We are migrating databases from Oracle to MySQL. Oracle and MySQL use a different character for the bind variables @ and :. We are using Dapper to query the database. We pass in DynamicParameters into Dapper and the bind variables work.

What I want to be able to do is go through the DynamicParameters and look at the name of the value and change the character on the front and then replace it in the SQL string as well. I know how I would do this.

The problem I have is that you cannot enumerate the DynamicParameters to get the key and value.

My ideas is to try and get hold of the private <string, DynamicParameters.ParamInfo> parameters field at runtime using reflection. I can't work out how to make it work as DynamicParameters.ParamInfo is a private class.

Any ideas on what I could do?

Accepted Answer

There are two parts to you question, first:

What I want to be able to do is go through the DynamicParameters and look at the name of the value and change the character on the front

and the second is:

then replace it in the SQL string as well

The first part got me interested to see how smart enough Dapper is. It proves that it is, smart enough, to handle the arguments passed to it in DynamicParameters. Consider you have the following:

// Source of the DynamicParameters
var args = new Dictionary<string,string>();
args.Add("@emailPromotion", "1");
// additional args goes here

// An example of how you build a DynamicParameters
var dbArgs = new DynamicParameters();
foreach (var pair in args) dbArgs.Add(pair.Key, pair.Value);

// The query - using SQL Server (AdventureWorks)
var sql = "select * from Person.Contact WHERE EmailPromotion = @EmailPromotion";

// The Dapper call (this works as expected)
var items = the_connection.Query<dynamic>(sql, dbArgs);    

Now let's say you migrated from Oracle using a colon and you passed your DynamicParameters from this source:

var oracle_args = new Dictionary<string,string>();
oracle_args.Add(":emailPromotion", "1");

If you use that oracle_args with the rest of the code given earlier it will still work. You would expect it won't as SQL Server couldn't understand the colon. The only thing that will cause an error is if the query itself (var sql) has the invalid character - the colon.

How then that relates to your question? This means that you don't have to worry about the "first part" and let Dapper do its job. You just have to take care of the "second part" and adjust your (sql) queries. And if you have total control of the queries then it should not give you any problem. A simple string replace would do the trick.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why