2010-09-16 12 views
8

Chcę utworzyć typ złożony do użycia w menedżerze encji z zapytania zbudowanego dynamicznie i wykonanego przy użyciu exec(). Czy to możliwe?; od kiedy piszę filtr, co byś zrobił zamiast tego, gdyby nie było to możliwe?Jak utworzyć typ złożony z procedury składowanej, która używa exec()?

Ponadto oceniam, używając linq, ale filtr wymaga wielu tabel i ich rejestrów, w związku z tym efektywność jest problemem.

Dzięki ...

+0

Ciekaw jestem, czy to exec() zwraca wiele zestawów rekordów, czy tylko jeden? – Markis

+0

wykonuje komendę sql w procedurze tsql. – JPCF

+0

Tego rodzaju zapytanie jest dokładnie tym, do czego służy LINQ2EF. Kiedy 'exec' na serwerze tracisz już nie tylko korzyści z wstępnej kompilacji, tracisz także korzyści z buforowanych planów wykonania, które uzyskają sparametryzowane zapytania. – JustLoren

Odpowiedz

4

Tak, można używać Entity Framework 4 i LINQ na górze, generuje zapytania sparametryzowanego i wykonuje go, to opcja.

Inną opcją jest (i zrobiłem kilka razy), aby utworzyć klasy bazowej/interfejs, powiedzmy:

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: 

} 

Następnie można tworzyć konkretne działania:

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 
    } 
} 

Bardzo łatwo tworzyć konkretne działania!

Następnie, aby uczynić go jeszcze łatwiej stworzyć ExecutionManager którego problemem jest sposób, aby uzyskać połączenie i wykonać działania:

public sealed ExecutionManager() { 

    TResult Execute<TResult>(IExecutable<TResult> action) { 
     var connection = OhOnlyIKnowHowTOGetTheConnectionAnfHereItIs(); 
     action.Execute(connection); 
     return action.Result; 
    } 
} 

Teraz wystarczy użyć go:

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 

Stosując ten prosty Technika jest bardzo łatwa do przeniesienia logiki połączenia/polecenia/wykonania z konkretnych działań do klasy bazowej, a konkretne działania dotyczą tylko generowania SQL i konwertowania danych wyjściowych bazy danych w pewne znaczące wyniki.

Powodzenia :)

+0

Hmmm ... tak ... ale bezpośrednio przez DB ... Pytam o to, ponieważ chcemy, aby procedury przechowywane były całkowicie zawarte w bazie danych. – JPCF

1

Jeśli zdecydujesz się pójść drogą Linq i szukasz dobrej drodze do zrobienia filtrowanie. LinqKit to świetna biblioteka do tworzenia predykatów ad-hoc. Problem z wbudowaną biblioteką linq polega na tym, że możesz łączyć ze sobą tylko instrukcje typu AND ad-hoc, nie możesz łączyć ad-hoc instrukcji OR. Linqkit sprawia, że ​​to powiew do osiągnięcia.

Powiązane problemy