Ajout de paramètres à IDbCommand
Je suis entrain de créer une petite fonction d'assistance au retour d'un DataTable
. Je voudrais travailler à travers tous les fournisseurs qui ADO.Net
prend en charge, j'ai donc pensé à faire tout usage IDbCommand
ou DbCommand
si possible.
J'ai atteint un point d'achoppement avec le code suivant:
private static DataTable QueryImpl(ref IDbConnection conn, String SqlToExecute, CommandType CommandType, Array Parameters)
{
SetupConnection(ref conn);
//set the capacity to 20 so the first 20 allocations are quicker...
DataTable dt = new DataTable();
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = SqlToExecute;
cmd.CommandType = CommandType;
if (Parameters != null && Parameters.Length > 0)
{
for (Int32 i = 0; i < Parameters.Length; i++)
{
cmd.Parameters.Add(Parameters.GetValue(i));
}
}
dt.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges);
}
return dt;
}
Lorsque ce code est exécuté, je reçois un InvalidCastException
qui stipule ce qui suit:
La SqlParameterCollection accepte uniquement les non-null SqlParameter type des objets, pas des objets String.
Le code tombe sur la ligne:
cmd.Parameters.Add(Parameters.GetValue(i));
Des idées?
Toutes les améliorations au code ci-dessus est apprécié.
Solution réelle:
private static readonly Regex regParameters = new Regex(@"@\w+", RegexOptions.Compiled);
private static DataTable QueryImpl(ref DbConnection conn, String SqlToExecute, CommandType CommandType, Object[] Parameters)
{
SetupConnection(ref conn);
DataTable dt = new DataTable();
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = SqlToExecute;
cmd.CommandType = CommandType;
if (Parameters != null && Parameters.Length > 0)
{
MatchCollection cmdParams = regParameters.Matches(cmd.CommandText);
List<String> param = new List<String>();
foreach (var el in cmdParams)
{
if (!param.Contains(el.ToString()))
{
param.Add(el.ToString());
}
}
Int32 i = 0;
IDbDataParameter dp;
foreach (String el in param)
{
dp = cmd.CreateParameter();
dp.ParameterName = el;
dp.Value = Parameters[i++];
cmd.Parameters.Add(dp);
}
}
dt.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges);
}
return dt;
}
Merci pour les idées et les liens etc. 🙂
- Ce n'Paramètres.GetValue faire?
- msdn.microsoft.com/en-us/library/system.array.getvalue.aspx
- Belle solution réelle. Cependant, la mise en DateTime.Maintenant à champ DateTime dans MS Access/OleDb échoue.
- J'ai entendu la solution pour éviter DateTime erreur est de mettre en millisecondes à zéro et qui permettra de résoudre l'incompatibilité de type de données d'erreur. Est-ce vrai? (Je me soucie de MS Access et SQL Server pour le moment).
Vous devez vous connecter pour publier un commentaire.
Je crois IDbCommand a un CreateParameter() méthode:
Vous pouvez ajouter le code de la accepté de répondre à une extension de la méthode:
Je sais que c'est pas ce que vous demandez, mais j'ai beaucoup plus simple et plus robuste solution à offrir.
Microsoft Modèles et Pratiques de la bibliothèque comprend une Application d'Accès aux Données du bloc qui est incroyablement puissant et facile à utiliser. Un exemple pour l'exécution d'une procédure stockée et le retour d'un jeu de données est illustré ci-dessous à partir de notre code:
Il n'a pas d'importance si la Connexion OleDb, ODBC, etc. Le ConnectionStringName dans la première ligne de code est juste le nom de la Consternating tel que défini dans la .fichier de configuration. Vous passez dans une Chaîne de Connexion nom de, procédure stockée nom, et un tableau d'objets, qui constituent les paramètres.
Ceci est juste l'un des nombreux sweet fonctions disponibles.
Vous aurez tout ce dont vous essayez de construire et puis certains.
Le site officiel est ici: http://msdn.microsoft.com/en-us/library/ff648951.aspx
Pour vous sauver la recherche, les classes de Données de la documentation sont disponibles ici: http://msdn.microsoft.com/en-us/library/microsoft.practices.enterpriselibrary.data(PandP.50).aspx
(et c'est gratuit à partir de Microsoft, et mis à jour régulièrement).
Votre
Parameters
paramètre doit être de typeIDataParameter[]
et, compte tenu de l'erreur de texte, la mise en œuvre concrète des besoins doit être unSqlParameter[]
type.Si vous souhaitez garder votre signature, vous aurez besoin d'une usine à dériver la nécessaire mise en œuvre concrète.
IDataParameter[]
n'est pas la cause du problème (bien qu'il serait préférable d'accepter uneArray
). Aussi, vous n'avez pas besoin d'une usine à créer le bon type de paramètre, comme ci-dessus,IDbCommand
a unCreateParameter
méthode, je vous recommande la suppression de cette réponse.Cette réponse est prévu pour un peu plus de but précis que ce que tu fais, mais en s'appuyant sur @Dismissile's réponse, j'ai utilisé un
Dictionary
de fournir le nom du paramètre et la valeur à uneforeach
boucle dans mon projet personnel.Ajouter
using System.Data.SqlClient;
etcmd.Parameters.Add(new SqlParameter("@parameterName", value));