小编典典

使用Dapper的存储库设计模式

c#

这可能是代码审查而不是堆栈溢出的问题。

我使用Dapper进行MicroORM检索并将数据保存到SQL Server2014。我在DTO
Proj中获得了DTO类,它们表示从数据库检索或保存到数据库的数据。

我正在使用存储库模式,因此在服务层上(如果需要存储库)我正在使用构造函数DI注入该依赖项,然后在存储库上调用方法来完成工作。

所以说我有两个名为CustomerService和CarService的服务。

然后,我有2个存储库,一个CustomerRepository和一个CarRepository。

我有一个接口,该接口定义每个存储库中的所有方法,然后定义具体的实现。

下面显示了一个示例方法(调用Stored Proc进行数据库INSERT(注意,存储的proc的实际字符串变量在类顶部定义为私有字符串)):

    public void SaveCustomer(CustomerDTO custDTO)
    {
        using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
        {
            db.Execute(saveCustSp, custDTO, commandType: CommandType.StoredProcedure);
        }
    }

一切正常,但是我发现自己在每个存储库的每个方法中都重复使用using块。我在下面概述了两个真实的问题。

有没有一种更好的方法,也许我可以使用BaseRepository类,而其他所有Repository都继承该类,而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);
            }
        }
}

但是,在我的存储库中,我还有其他方法,例如:

    public bool IsOnlyCarInStock(int carId, int year)
    {
        using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
        {
            var car = db.ExecuteScalar<int>(anotherStoredSp, new { CarID = carId, Year = year },
                                commandType: CommandType.StoredProcedure);

            return car > 0 ? true : false;
        }
    }

    public IEnumerable<EmployeeDTO> GetEmployeeDetails(int employeeId)
    {
        using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
        {
            return db.Query<EmployeeDTO>(anotherSp, new { EmployeeID = employeeId },
                                commandType: CommandType.StoredProcedure);
        }
    }

使用通用类型T将这些添加到我的基本存储库的正确方法是什么,以便我可以返回任何类型的DTO或任何C#本机类型


阅读 650

收藏
2020-05-19

共1个答案

小编典典

当然,用于创建和处理Connection的功能会很好用。

protected void Execute(Action<IDbConnection> query)
{
    using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
    {
        query.Invoke(db);
    }
}

而您的简化呼叫站点:

public void SaveCustomer(CustomerDTO custDTO)
{
    Execute(db => db.Execute(saveCustSp, custDTO, CommandType.StoredProcedure));
}

具有返回值:

public T Get<T>(Func<IDbConnection, T> query)
{
    using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
    {
        return query.Invoke(db); 
    }
}

在呼叫站点中,只需编写要使用的逻辑即可。

public IEnumerable<EmployeeDTO> GetEmployeeDetails(int employeeId)
{
    return Get<IEnumerable<EmployeeDTO>(db => 
        db.Query<EmployeeDTO>(anotherSp, new { EmployeeID = employeeId }, CommandType.StoredProcedure));
}
2020-05-19