Я борюсь с тем, как правильно реализовать репозитории.Все операции с данными должны выполняться с помощью хранимых процедур (я не хочу спорить, правильно это или нет)
При запуске я регистрирую dbcontext
.dbcontext
позволяет мне читать данные из базы данных благодаря объектам DbQuery
и DbSet
.
Но мне также нужно реализовать интерфейс репозитория, который я пробовал.Но моя реализация позволяет мне выполнять хранимые процедуры только через ExecuteSqlCommand
, но я не могу использовать DbQuery
или DBSet
объекты для извлечения данных.
Я хотел бы использовать DbQuery
, DbSet
, а также ExecuteSqlCommand
в одной репозитории реализации.Как это сделать ?Должен ли я создать new DbContext
в каждом хранилище или поделиться DbContext via dependency injection
или хранилище должно наследовать DbContext
?
Startup.cs
services.AddDbContext<Database>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
DbContext
public class Database : DbContext
{
public Database(DbContextOptions<Database> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public virtual DbQuery<Business> Business { get; set; }
// working
public IEnumerable<Business> GetBusiness(int id)
{
var query = @"exec query.usp_GetBusiness @id";
var p1 = new SqlParameter("@id", id);
return Business.FromSql(query, p1).ToList();
}
}
BusinessRepository.cs Iиметь собственный репозиторий, который позволяет выполнять хранимые процедуры
public class BusinessRepository :IBusinessRepository
{
private readonly IHttpContextAccessor _httpAccessor;
private readonly DatabaseFacade database;
public BusinessRepository(IConfiguration configuration, IHttpContextAccessor httpAccessor)
{
DbContextOptions dbContextOptions = new DbContextOptionsBuilder()
.UseSqlServer(configuration.GetConnectionString("DefaultConnection"))
.Options;
database = new DbContext(dbContextOptions).Database;
_httpAccessor = httpAccessor;
}
// working
public void UpdateBusinessName(string Name)
{
database.ExecuteSqlCommand("exec command.usp_UpdateBusinessName @user, @name",
new SqlParameter("user", _httpAccessor.HttpContext.User.Identity.Name),
new SqlParameter("name", Name)
);
}
// this does not work, because repository does not inherit from dbContext
public virtual DbQuery<Business> Business { get; set; }
// not working, Business.FromSql(query, p1) returns ArgumentNullException !
public IEnumerable<Business> GetBusiness(int id)
{
var query = @"exec query.usp_GetBusiness @id";
var p1 = new SqlParameter("@id", id);
return Business.FromSql(query, p1).ToList();
}
}
Суть вопроса
Это хорошая идея, чтобы обернуть все репозитории в некоторыеОбъект masterRepository и репозитории вызовов, такие как masterRepository.businessRepository.GetBusiness()
, преимущество в том, что я могу ввести только один объект в качестве параметра, который содержит все команды, недостатком является то, что я создаю экземпляр репозиториев, которые я не использую для каждого запроса.Что вы думаете?
Я знаю, что это сложный вопрос, поэтому я очень благодарен за ответы.