Как я могу использовать хранимую процедуру + репозиторий + блок шаблонов работы в Entity Framework?
Сначала у меня есть проект веб-приложения MVC с кодом Entity Framework. В этом проекте я собираюсь использовать общий репозиторий и единицу рабочих шаблонов. Кроме того, я хочу использовать хранимые процедуры для получения списка с помощью методов get-list
.
Как я могу использовать хранимые процедуры с общим хранилищем и единицей рабочих шаблонов?
Ответы
Ответ 1
В общий репозиторий добавить
public IEnumerable<T> ExecWithStoreProcedure(string query, params object[] parameters)
{
return _context.Database.SqlQuery<T>(query, parameters);
}
И затем вы можете вызвать его с помощью любого unitofwork/репозитория, например
IEnumerable<Products> products =
_unitOfWork.ProductRepository.ExecWithStoreProcedure(
"spGetProducts @bigCategoryId",
new SqlParameter("bigCategoryId", SqlDbType.BigInt) { Value = categoryId }
);
Ответ 2
Разрабатывая ответ @sunil и мой комментарий к нему, я создал класс специально для обработки хранимых процедур. Как я уже упоминал в своем комментарии, если вы ожидаете от модели другой модели, отличной от той, что указана в вашем репозитории, у вас есть проблемы. Кроме того, если вы хотите только выполнить SP, то вы нарушаете ISP. Ниже мое решение. Это отнюдь не является окончательным и может быть легко расширено или изменено в соответствии с вашими потребностями.
public class ProcedureManager : IProcedureManager
{
internal DbContext Context;
public ProcedureManager(DbContext context)
{
Context = context;
}
//When you expect a model back (async)
public async Task<IList<T>> ExecWithStoreProcedureAsync<T>(string query, params object[] parameters)
{
return await Context.Database.SqlQuery<T>(query, parameters).ToListAsync();
}
//When you expect a model back
public IEnumerable<T> ExecWithStoreProcedure<T>(string query)
{
return Context.Database.SqlQuery<T>(query);
}
// Fire and forget (async)
public async Task ExecuteWithStoreProcedureAsync(string query, params object[] parameters)
{
await Context.Database.ExecuteSqlCommandAsync(query, parameters);
}
// Fire and forget
public void ExecuteWithStoreProcedure(string query, params object[] parameters)
{
Context.Database.ExecuteSqlCommand(query, parameters);
}
}
Ответ 3
Для общего репозитория Добавьте это:
public IEnumerable<TEntity> GetdataFromSqlcommand(string command, System.Data.SqlClient.SqlParameter[] parameter)
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append($"EXECUTE {command}");
strBuilder.Append(string.Join(",", parameter.ToList().Select(s => $" @{s.ParameterName}")));
return Context.Set<TEntity>().FromSql(strBuilder.ToString(), parameter);
}
И вам просто нужно отправить имя хранимой процедуры и массив параметров:
public IEnumerable<MainData> GetMainData(Param query)
{
var param1 = new SqlParameter("param1", query.param1);
var param2 = new SqlParameter("param2", query.param2);
return GetdataFromSqlcommand("StoredProcedurename", parameter: new[] { param1, param2 }).ToList();
}
Ответ 4
это работает в моем случае
IQueryable<Cm_Customer> customerQuery = _uow.SqlQuery<Cm_Customer>(@" DECLARE @UserId INT = {0}
EXEC Cm_GetCustomersByUserId @UserId", filter.UserId).AsQueryable();
и метод единицы работы
public IEnumerable<TEntity> SqlQuery<TEntity>(string sql, params object[] parms)
{
return _context.Database.SqlQuery<TEntity>(sql, parms);
}