我在努力正确实施存储库。所有数据操作都必须通过存储过程完成(我不想争辩是对还是错)
在启动中,我注册dbcontext
。 dbcontext
和DbQuery
对象使我可以从数据库中读取数据。
但是我还需要实现我尝试过的存储库接口。但是我的实现只允许我通过DbSet
执行存储过程,但是我无法使用ExecuteSqlCommand
或DbQuery
对象来检索数据。
我想在一个存储库实现中使用DBSet
,DbQuery
以及DbSet
。怎么做 ?我应该在每个存储库中创建ExecuteSqlCommand
还是共享new DbContext
还是存储库继承DbContext via dependency injection
?
Startup.cs
DbContext
DbContext
services.AddDbContext<Database>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
BusinessRepository.cs 我有自定义存储库,可以执行存储过程
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();
}
}
问题底线
将所有存储库包装到某个masterRepository对象并调用诸如 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();
}
}
之类的存储库是个好主意,优点是我只能输入一个对象作为包含所有命令的参数,缺点是我创建了存储库实例我不使用每个请求。你觉得呢?
我知道这是一个复杂的问题,因此我非常感谢您的回答。
答案 0 :(得分:0)
我听取了评论的建议,这是我第一个可行的解决方案。这可能不是最佳做法,但至少可以奏效。
Startup.cs
services.AddDbContext<AppContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
DbContext
public class AppContext : DbContext
{
public AppContext (DbContextOptions<AppContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public virtual DbQuery<Business> Business { get; set; }
}
BusinessRepository.cs
public class BusinessRepository :IBusinessRepository
{
private readonly AppContext _context;
public BusinessRepository(AppContext context)
{
_context = context;
}
// working
public IEnumerable<Business> GetBusiness(int id)
{
var query = @"exec query.usp_GetBusiness @id";
var p1 = new SqlParameter("@id", id);
return _context.Business.FromSql(query, p1).ToList();
}
// working
public void UpdateBusinessName(string name, string user)
{
_context.Database.ExecuteSqlCommand("exec command.usp_UpdateBusinessName @user, @name",
new SqlParameter("user", user),
new SqlParameter("name", name)
);
}
}