Oui, vous pouvez utiliser Entity Framework 4 et LINQ sur le dessus, il génère la requête et l'exécute paramétrisé, qui est l'option.
Une autre option est (et je l'ai fait plusieurs fois) pour créer une classe de base/interface, disons:
public interface IExecutable
{
void Execute(IConnection connection);
}
public interface IExecutable<TResult> : IExecutable
{
TResult Result { get; }
}
public abstract ActionBase<TResult> : IExecutable<TResult>
{
protected void AddParameter(....);
protected IDataReader ExecuteAsReader(string query) {
//create a DB Command, open transaction if needed, execute query, return a reader.
}
protected object ExecuteAsScalar(string query) {
//....
}
//the concrete implementation
protected abstract TResult ExecuteInternal();
IExecutable.Execute(IConnection connection) {
//keep the connection
this.Result = ExecuteInternal();
}
//another common logic:
}
Ensuite, vous pouvez créer vos actions concrètes:
public sealed class GetUsersAction : ActionBase<<IList<User>>
{
//just a constructor, you provide it with all the information it neads
//to be able to generate a correct SQL for this specific situation
public GetUsersAction(int departmentId) {
AddParameter("@depId", departmentId);
}
protected override IList<User> ExecuteInternal() {
var command = GenerateYourSqlCommand();
using(var reader = ExecuteAsReader(command)) {
while(reader.Read) {
//create your users from reader
}
}
//return users you have created
}
}
Très facile à créer des actions concrètes!
Ensuite, pour le rendre encore plus facile, créer un ExecutionManager dont le souci est de savoir comment obtenir la connexion et exécuter l'action:
public sealed ExecutionManager() {
TResult Execute<TResult>(IExecutable<TResult> action) {
var connection = OhOnlyIKnowHowTOGetTheConnectionAnfHereItIs();
action.Execute(connection);
return action.Result;
}
}
maintenant simplement l'utiliser:
var getUsersAction = new GetUsersAction(salesDepartmentId);
//it is not necessary to be a singletone, up to you
var users = ExecutionManager.Instance.Execute(getUsersAction);
//OR, if you think it is not up to ExecutionManager to know about the results:
ExecutionManager.Instance.Execute(getUsersAction);
var users = getUsersAction.Result
En utilisant ce simple technique Il est vraiment facile de déplacer toute la logique connexion/commande/exécution des actions concrètes dans la classe de base, et les préoccupations des actions concrètes génèrent juste des SQL et convertissent la sortie de la base de données en résultats significatifs.
Bonne chance :)
Je suis curieux que exec() renvoie plusieurs jeux d'enregistrements ou juste un? – Markis
il exécute une commande sql sur une procédure tsql – JPCF
Ce type de requête est exactement ce que LINQ2EF est pour. Lorsque vous exécutez 'exec 'sur le serveur, vous perdez déjà non seulement les avantages de la pré-compilation, mais vous perdez également les avantages des plans d'exécution mis en cache que les requêtes paramétrées obtiennent. – JustLoren