Dapper's creators were very aware of this problem. This kind of functionality is really needed for INSERT and UPDATE helpers The Query Execute and QueryMultiple methods take in a dynamic parameter. This can either be an anonymous type, a concrete type or an object that implements IDynamicParameters public interface IDynamicParameters { void AddParameters(IDbCommand command, Identity identity); } This interface is very handy AddParameters is called just before running any SQL.
Not only does this give you rich control over the parameters sent to SQL. It allows you to hook up DB specific DbParameters, since you have access to the command (you can cast it to the db specific one). This allows for support of Table Values Parameters and so on Dapper contains an implementation of this interface that can be used for your purposes called DynamicParameters This allows you to both concatenated anonymous parameter bags and add specific values You can use the method AddDynamicParams to append an anonymous type var p = new DynamicParameters(); p.
AddDynamicParams(new{a = "1"}); p. AddDynamicParams(new{b = "2", c = "3"}); p. Add("d", "4") var r = cnn.
Query("select @a a, @b b, @c c, @d d", p); // r. A == 1, r. B == 2, r.
C == 3, r. D == 4.
Dapper's creators were very aware of this problem. This kind of functionality is really needed for INSERT and UPDATE helpers. The Query, Execute and QueryMultiple methods take in a dynamic parameter.
This can either be an anonymous type, a concrete type or an object that implements IDynamicParameters. Public interface IDynamicParameters { void AddParameters(IDbCommand command, Identity identity); } This interface is very handy, AddParameters is called just before running any SQL. Not only does this give you rich control over the parameters sent to SQL.It allows you to hook up DB specific DbParameters, since you have access to the command (you can cast it to the db specific one).
This allows for support of Table Values Parameters and so on. Dapper contains an implementation of this interface that can be used for your purposes called DynamicParameters. This allows you to both concatenated anonymous parameter bags and add specific values.
You can use the method AddDynamicParams to append an anonymous type. Var p = new DynamicParameters(); p. AddDynamicParams(new{a = "1"}); p.
AddDynamicParams(new{b = "2", c = "3"}); p. Add("d", "4") var r = cnn. Query("select @a a, @b b, @c c, @d d", p); // r.
A == 1, r. B == 2, r. C == 3, r.
D == 4.
In C#, I would like to figure out if it's possible to declare an anonymous type where the fields are not known until run-time. Anonymous types are generated by the compiler. You want to know if the compiler will generate you a compiler-generated type with field types not known to the compiler.
Clearly it cannot do so; as you correctly surmise, you are out of luck. I've seen several questions on StackOverflow asking about extending anonymous types after they are declared ("extendo objects") We usually call those "expando" objects. If what you want to do is make an expando object based on a dictionary of key-value pairs, then use the ExpandoObject class to do that.
See this MSDN article for details: msdn.microsoft.com/en-us/magazine/ff7962... If what you want to do is generate a bona-fide . NET class at runtime, you can do that too. As you correctly note, you need some fancy reflection to do so.
What you want to do is make a collectible assembly (so-called because unlike a normal assembly, you generate it at runtime and the garbage collector will clean it up when you are done with it. ) See msdn.microsoft.com/en-us/library/dd55493... for details on how to make a collectible assembly and emit a type into it using a TypeBuilder.
Sorry for the confusion, "ExpandoObject" is what I meant to type =) I am not yet sure which of your suggested options will work for me, I need to do some experimentation with passing different objects into Dapper, and see what works and what doesn't. RE: your first paragraph, I think I had pretty much convinced myself it wouldn't work by the time I finished typing out my question! You laid it out in a very clear fashion, thank you!
=) – Egahn Sep 15 at 20:48 1 The trouble with Expandos and dapper is that there is no internal special handling for them so the params will not be extracted from the underlying IDictionary or whatever. That is why in this context you probably want to use IDynamicParameters @Egahn ... you can meld and generate a new type out of 2 anon types using reflection. Emit but in this context you do not need to.
– Sam Saffron? Sep 16 at 11:26.
You can't use an anonymous type. Anonymous types are generated by the compiler rather than at run-time. You could certainly use dynamic though: dynamic dynamicObj = new ExpandoObject(); var objAsDict = (IDictionary)dynamicObj; foreach(var item in paramList) { objAsDict.
Add(item. Item1, item. Item2); } You can then use dynamicObj as a regular object: Console.
WriteLine(dynamicObj. Key1); // would output "value1.
Fascinating, I did not know you could do that. I'll have to experiment with doing this and passing the resulting object into Dapper to see if it works. The problem I foresee is, I believe the parameter name in the SQL query string that I pass into Dapper determines what field it attempts to access on the parameters object I also pass into Dapper... so if my SQL query has a parameter like "@A" in it, the parameters object I pass in needs a field called "A".
I'll give this a try though. – Egahn Sep 15 at 20:44 I'm not in front of my computer, but how does that work? Wouldn't you have to at least cast it to a DICTIONARY not an IDICTIONARY?
I don't think there is any chance that casting it to an interface would magically IMPLEMENT the add method. I understand it would compile, but it won't actually add it to the collection right? – John Buchanan Sep 15 at 21:29 @John Buchanan - ExpandoObject implements IDictionary.
IDictionary contains the Add(TKey, TValue) method. Therefore, once you cast to IDictionary...Add works. – Justin Niessner Sep 15 at 21:55 @Justin Niessner - Sorry for my ignorance, but why the cast?
Since ExpandoObject implements IDictionary, why not just dynamicObj.Add()? – John Buchanan Sep 150 at 1:38.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.