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 :)
Ciekaw jestem, czy to exec() zwraca wiele zestawów rekordów, czy tylko jeden? – Markis
wykonuje komendę sql w procedurze tsql. – JPCF
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