目前,我正在尝试使用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) 有几个很好的博客关于如何使用泛型类实现存储库模式以及工作单元模式.
想法是定义一个通用接口IRepository和一个隐藏数据实际访问方式的类存储库.可以使用Entity Framework DbContext访问它,也可以使用存储库作为内存集合进行单元测试.
public interface public interface IRepository<T> where T : class
{
T GetById(int Id);
void DeleteById(int Id);
void Add(T entity);
void Update(T entity);
etc.
}
Run Code Online (Sandbox Code Playgroud)
我经常看到添加了几个类似于Queryable和/或Enumerable函数的Query函数.
例如,在实现数据访问层中,我看到:
/// Returns an IEnumerable based on the query, order clause and the properties included
/// <param name="query">Link query for filtering.</param>
/// <param name="orderBy">Link query for sorting.</param>
/// <param name="includeProperties">Navigation properties seperated by comma for eager loading.</param>
/// <returns>IEnumerable containing the resulting entity set.</returns>
IEnumerable<T> …Run Code Online (Sandbox Code Playgroud) 关于存储库模式,我有几个问题:
如果仅使用离线数据库(例如Room with LiveData),那么是否使用存储库模式?
如果我的应用程序当前处于脱机状态,但将来会连接到远程数据库,那么我应该实现存储库模式,还是以后再做就不会有问题了?
我有一个Generic Repository像下面的处理我的CRUD,对于一个单一的实体它易于使用,问题开始时,我尝试加入我的POCOs.
假设我有这些POCO,它们使用流畅的api(多对多和一对多关系)进行映射:
public class Student
{
public Student()
{
this.Courses = new HashSet<Course>();
}
public int StudentId { get; set; }
public string StudentName { get; set; }
//FKs
public virtual Standard Standard { get; set; }
public int StdandardRefId { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
public Course()
{
this.Students = new HashSet<Student>();
}
public int CourseId { get; set; }
public …Run Code Online (Sandbox Code Playgroud)