Here’s the setup: I have an Open Source project called Massive and I’m slinging around dynamics as a way of creating SQL on the fly, and dynamic result sets on the fly.
To do the database end of things I’m using System.Data.Common and the ProviderFactory stuff. Here’s a sample that works just fine (it’s static so you can run in a Console):
static DbCommand CreateCommand(string sql) {
return DbProviderFactories.GetFactory("System.Data.SqlClient")
.CreateCommand();
}
static DbConnection OpenConnection() {
return DbProviderFactories.GetFactory("System.Data.SqlClient")
.CreateConnection();
}
public static dynamic DynamicWeirdness() {
using (var conn = OpenConnection()) {
var cmd = CreateCommand("SELECT * FROM Products");
cmd.Connection = conn;
}
Console.WriteLine("It worked!");
Console.Read();
return null;
}
The result of running this code is “It worked!”
Now, if I change the string argument to dynamic – specifically an ExpandoObject (pretend that there’s a routine somewhere that crunches the Expando into SQL) – a weird error is thrown. Here’s the code:

What worked before now fails with a message that makes no sense. A SqlConnection is a DbConnection – moreover if you mouseover the code in debug, you can see that the types are all SQL types. “conn” is a SqlConnection, “cmd” is a SqlCommand.
This error makes utterly no sense – but more importantly it’s cause by the presence of an ExpandoObject that doesn’t touch any of the implementation code. The differences between the two routines are:
1 – I’ve changed the argument in CreateCommand() to accept “dynamic” instead of string
2 – I’ve created an ExpandoObject and set a property.
It gets weirder.
If simply use a string instead of the ExpandoObject – it all works just fine!
//THIS WORKS
static DbCommand CreateCommand(dynamic item) {
return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateCommand();
}
static DbConnection OpenConnection() {
return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
}
public static dynamic DynamicWeirdness() {
dynamic ex = new ExpandoObject();
ex.TableName = "Products";
using (var conn = OpenConnection()) {
//use a string instead of the Expando
var cmd = CreateCommand("HI THERE");
cmd.Connection = conn;
}
Console.WriteLine("It worked!");
Console.Read();
return null;
}
If I swap out the argument for CreateCommand() to be my ExpandoObject (“ex”) – it causes all of the code to be a “dynamic expression” which is evaluated at runtime.
It appears that the runtime evaluation of this code is different than compile-time evaluation… which makes no sense.
**EDIT: I should add here that if I hard-code everything to use SqlConnection and SqlCommand explicitly, it works 🙂 – here’s an image of what I mean:

When you pass the dynamic to
CreateCommand, the compiler is treating its return type as a dynamic that it has to resolve at runtime. Unfortunately, you’re hitting some oddities between that resolver and the C# language. Fortunately, it’s easy to work around by removing your use ofvarforcing the compiler to do what you expect:This has been tested on Mono 2.10.5, but I’m sure it works with MS too.