Voici la configuration: j'ai un projet Open Source appelé "Massive" (github/robconery/massif) et je suis d'élingage autour de la dynamique comme un moyen de création de SQL à la volée, et de la dynamique des ensembles de résultats à la volée.
Pour faire la base de données de la fin des choses, je suis en utilisant le Système.Les données.Commune et de la ProviderFactory choses. Voici un exemple qui fonctionne très bien (il est statique de sorte que vous pouvez exécuter dans une 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;
}
Le résultat de l'exécution de ce code est "Ça marche!"
Maintenant, si je change l'argument de chaîne dynamique - plus précisément un ExpandoObject (faire semblant qu'il y a une routine de quelque part qui croque la Expando en SQL) - une étrange erreur est renvoyée. Voici le code:
Ce qui a fonctionné avant maintenant échoue avec un message qui n'a aucun sens. Une occurrence de SqlConnection est un DbConnection - d'ailleurs si vous passer la souris sur le code de débogage, vous pouvez voir que les types sont tous les types SQL. "conn" est une occurrence de SqlConnection, "cmd" est un SqlCommand.
Cette erreur fait absolument aucun sens - mais le plus important c'est cause par la présence d'un ExpandoObject qui ne touche pas toute la mise en œuvre du code. Les différences entre les deux routines sont: 1 - j'ai changé l'argument en CreateCommand() pour accepter les "dynamique" au lieu de string 2 - j'ai créé un ExpandoObject et de définir une propriété.
Il devient encore plus bizarre.
Si il suffit d'utiliser une chaîne de caractères au lieu de la ExpandoObject - tout cela fonctionne très bien!
//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;
}
Si je remplace les arguments pour CreateCommand() pour être mon ExpandoObject ("ex") -, il provoque tout le code à une "dynamique de l'expression" qui est évaluée au moment de l'exécution.
Il semble que le moteur d'exécution de l'évaluation de ce code est différent de celui de la compilation d'évaluation en temps... ce qui n'a pas de sens.
**EDIT: je dois ajouter ici que si je code en dur tout à l'utilisation de SqlConnection et SqlCommand explicitement, il fonctionne :) - voici une image de ce que je veux dire: