Vous pouvez utiliser le même technique que j'ai utilisé pour écrire ADONETHelper.
Vérifiez également le code du projet intitulé HowToUseADONETHelper.
La principale méthode est la suivante:
T Execute<T>(string sql, CommandType commandType, Func<IDbCommand, T> function, params IDbDataParameter[] parameters)
{
using (var con = new TConnection()) // replace TConnection with your connection object
{
con.ConnectionString = _ConnectionString;
using (var cmd = new NpgsqlCommand())
{
cmd.CommandText = sql;
cmd.Connection = con;
cmd.CommandType = commandType;
if (parameters.Length > 0)
{
foreach (var parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
}
con.Open();
return function(cmd);
}
}
}
Notez que la méthode Execute accepte un argument de type Func<IDbCommand, T>
- ce fait vous permet de faire toutes sortes de choses intéressantes:
Ensuite, vous pouvez utiliser certains d'autres exécuter pour vous simplifier la surcharge code:
Execute non requête:
public int ExecuteNonQuery(string sql, CommandType commandType, params IDbDataParameter[] parameters)
{
return Execute<int>(sql, commandType, c => c.ExecuteNonQuery(), parameters);
}
C'est assez simple - la fonction que vous envoyez à la méthode Execute
est simplement c => c.ExecuteNonQuery()
- et comme vous le savez, le ExecuteNonQuery dans l'interface IDbCommand retourne un int
, donc Execute
sera également de retour int
.
Exécuter Scalar:
public T ExecuteScalar<T>(string sql, CommandType commandType, params IDbDataParameter[] parameters)
{
return Execute<T>(sql, commandType, c =>
{
var returnValue = c.ExecuteScalar();
return (returnValue != null && returnValue != DBNull.Value && returnValue is T)
? (T)returnValue
: default(T);
}, parameters);
}
Ici, la fonction est un peu plus compliqué. Le ExecuteScalar()
de IDbCommand
renvoie un Object
. Ce Object
peut être nul, il peut être DBNull, ou il peut s'agir d'une chaîne, int, ou n'importe quel type de données pris en charge par votre base de données. Donc, ce que je fais est d'utiliser une condition qui renvoie le default
de T
lorsque la valeur retournée par ExecuteScalar
est null
ou DBNull
, ou simplement le object
de lancer à T
et le renvoyer.
Execute Lecteur:
// Here, you do the actuall reading from the dataReader in the populate function
public bool ExecuteReader(string sql, CommandType commandType, Func<IDataReader, bool> populate, params IDbDataParameter[] parameters)
{
return Execute<bool>(sql, commandType, c => populate(c.ExecuteReader()), parameters);
}
Assez simple, non?la fonction populate pourrait ressembler à ceci:
bool Populate(IDataReader reader)
{
var obj = new MyClass();
while(reader.Read())
{
obj.PropertyA = reader.GetValueOrDefault("A"); // That method is written in the IDataReaderExtestion class in ADONETHelper
}
return true;
}
et remplir un ensemble de données:
public DataSet FillDataSet(string sql, CommandType commandType, params IDbDataParameter[] parameters)
{
return Execute<DataSet>(sql, commandType, c => FillDataSet(c), parameters);
}
private DataSet FillDataSet(IDbCommand command)
{
var dataSet = new DataSet();
using (var adapter = new TAdapter())
{
adapter.SelectCommand = command;
adapter.Fill(dataSet);
}
return dataSet;
}
En fait, je aurais pu faire la même chose ici avec l'exécution de lecteur, et d'écrire la méthode FillDataSet
comme une expression lambda, je ne me souviens pas pourquoi j'ai décidé d'écrire le FillDataSet
comme une méthode différente. Cependant, c'est la méthode que je passe en tant qu'argument function
à la méthode Execute
. Il utilise simplement un DataAdapter pour remplir l'ensemble de données. Notez que vous devez changer le TAdapter
en NpgsqlDataAdapter
dans votre cas.
Aimez votre réponse, aimerais voir plus de code commenté si possible, car je peux le copier/coller/le modifier sans comprendre certaines parties, mais ce n'est pas ce que je veux. –
Si vous me dites quelles parties vous ne comprenez pas je peux l'expliquer ... –
La chose principale im confus à propos de est "Execute Scalar" et "dataset", ne comprends pas certaines parties de l'appel de retour dans ces méthodes, donc si vous serait si aimable de commenter ces parties, serait reconnaissant =) –