I am trying to have dapper return List<KeyValuePair<int, dynamic>>
I have made what I believe to be the absolute simplest possible query to illustrate the issue:
using (SqlConnection conn = new SqlConnection(_connectionString))
{
return conn.Query<int, string, bool, KeyValuePair<int, dynamic>>("SELECT 1 AS 'SomeInt', 'A' AS 'SomeString', 'True' AS 'SomeBool'", (i, s, b) =>
new KeyValuePair<int, dynamic>(
i,
new
{
TheString = s,
TheBool = b
}
), splitOn: "SomeString").AsList();
}
When I try to run this I get System.ArgumentException: 'When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id
.
I think that I am specifying the splitOn
parameter correctly as SomeString
... ?
I have looked at a number of other SO questions regarding this error including Dapper Multi-mapping Issue, When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn, and Correct use of Multimapping in Dapper, and if the answer is in one of those I can't find it.
I specifically tried to mirror what the answer here Correct use of Multimapping in Dapper, but it doesn't work for me.
I did notice that in the vast majority of other examples, the code looks like conn.Query<x, y, x>
(i.e. the return value is listed as the first value as well). I'm not sure if this matters or not, or even if I'm able to do what I want. I'm pretty new to Dapper.
Thank you in advance!
You'll need to add the other fields in the splitOn
value because each is a distinct class. Since each could be mapped to a separate POCO class, but in your case each is a distinct value.
using (SqlConnection conn = new SqlConnection(_connectionString))
{
return conn
.Query<int, string, string, KeyValuePair<int, dynamic>>(
"SELECT 1 AS 'SomeInt', 'A' AS 'SomeString', 'True' AS 'SomeBool'",
(i, s, b) =>
new KeyValuePair<int, dynamic>(
i,
new
{
TheString = s,
TheBool = Convert.ToBoolean(b)
}),
splitOn: "SomeInt,SomeString,SomeBool")
.AsList();
}
Also I had to fix the boolean, since it was not converted correctly. Maybe in your case it's read from an actual database table and would work.
To illustrate the power of splitOn
, take the following modification to the previous answer. This one splits the 3 values returned from the SQL query as 2 objects, the 1st into the int
object and the 2nd and 3rd into a single dynamic
object:
conn
.Query<int, dynamic, KeyValuePair<int, dynamic>>(
"SELECT 1 AS 'SomeInt', 'A' AS 'SomeString', 'True' AS 'SomeBoolean'",
map: (i, d) => new KeyValuePair<int, dynamic>(i, new
{
TheString = d.SomeString,
TheBool = d.SomeBoolean
}),
splitOn: "SomeInt,SomeString")
.AsList();