2010-09-16 3 views
8

Je souhaite créer un type complexe à utiliser dans un gestionnaire d'entités à partir d'une requête créée dynamiquement et exécutée avec exec(). C'est possible?; puisque j'écris un filtre, que feriez-vous à la place si ce n'est pas possible?Comment créer un type complexe à partir d'une procédure stockée qui utilise exec()?

En outre, j'évalue en utilisant linq, mais le filtre a besoin de nombreuses tables et de leurs registres, donc l'efficacité est un problème.

... Merci

+0

Je suis curieux que exec() renvoie plusieurs jeux d'enregistrements ou juste un? – Markis

+0

il exécute une commande sql sur une procédure tsql – JPCF

+0

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

Répondre

4

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 :)

+0

Hmmm ... oui ... mais directement sur la base de données ... Je demande cela parce que nous voulons que les procédures stockées soient entièrement contenues dans la base de données. – JPCF

1

Si vous décidez d'emprunter la voie LINQ et êtes à la recherche d'une bonne façon de faire le filtrage. LinqKit est une excellente bibliothèque pour créer des prédicats ad-hoc. Le problème avec la bibliothèque linq intégrée est que vous ne pouvez combiner que des instructions AND ad-hoc, vous ne pouvez pas combiner des instructions OR ad-hoc. Linqkit est un jeu d'enfant à accomplir.

Questions connexes