目前,我正在尝试使用Dapper ORM与工作单元+存储库模式.
我想使用工作单元而不是简单的dapper存储库,因为我的插入和更新需要一定程度的事务处理.我一直无法找到任何有用的例子,因为大多数似乎使用实体框架并且在工作单元内存在泄漏问题.
有人可以指点我正确的方向吗?
这可能是代码审查的问题,而不是堆栈溢出.
我正在使用Dapper for MicroORM来检索并将数据保存到SQL Server 2014.我在DTO Proj中有DTO类,它代表从DB检索到的数据或保存到DB.
我正在使用存储库模式,所以在我的服务层,如果需要存储库,我使用构造函数DI来注入该依赖项,然后调用存储库上的方法来完成工作.
所以假设我有2个名为CustomerService和CarService的服务.
然后,我有2个存储库,一个CustomerRepository和一个CarRepository.
我有一个接口,它定义每个存储库中的所有方法,然后定义具体的实现.
下面显示了一个示例方法(调用Stored Proc来执行DB INSERT(注意存储过程的实际字符串变量被定义为类顶部的私有字符串):
public void SaveCustomer(CustomerDTO custDTO)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
db.Execute(saveCustSp, custDTO, commandType: CommandType.StoredProcedure);
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好但我发现自己在每个存储库中的每个方法中重复使用块.我有两个真正的问题,如下所述.
有没有更好的方法,我可能会以某种方式使用BaseRepository类,每个其他存储库继承,Base将实现数据库连接的实例化?
对于系统上的多个并发用户,这仍然可以正常工作吗?
********更新
根据Silas的回答,我创建了以下内容
public interface IBaseRepository
{
void Execute(Action<IDbConnection> query);
}
public class BaseRepository: IBaseRepository
{
public void Execute(Action<IDbConnection> query)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
{
query.Invoke(db);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在我的存储库中,我有其他方法,如下所示:
public bool IsOnlyCarInStock(int carId, int year)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString)) …Run Code Online (Sandbox Code Playgroud) 由于我无法从Linq到Entities查询返回这些类型中的任何一种,因此我坚持返回List.
从DB调用返回时(在单独的WCF服务或DLL中),Controller中的代码失败,因为dbcontext连接已关闭.
请注意以下代码.对于IEnumerable和IQueryable,由于以上描述,数据不会返回.
// Controller
IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList().AsEnumerable();
// Error coming back because dbcontext connection was closed.
ViewBag.ProjectsCust = new SelectList(projectDdl, "ProjectId", "Name");
Run Code Online (Sandbox Code Playgroud)
// WCF Service or DLL
public IEnumerable<ProjectDescription> GetProjectDropDownList()
{
try
{
//IQueryable<ProjectDescription> project = null;
using (YeagerTechEntities DbContext = new YeagerTechEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Database.Connection.Open();
IEnumerable<ProjectDescription> project = DbContext.Projects.Select(s =>
new ProjectDescription()
{
ProjectID = s.ProjectID,
Description = s.Description
}
);
return project;
}
}
catch (Exception ex)
{
throw ex; …Run Code Online (Sandbox Code Playgroud)