Microsoft.AspNetCore.All : v2.0.3 | Dapper : v1.50.2
Tôi không chắc liệu mình có đang sử dụng các phương pháp hay nhất một cách chính xác hay không, nhưng tôi đang làm theo cách này, để xử lý nhiều chuỗi kết nối.
Thật dễ dàng nếu bạn chỉ có 1 chuỗi kết nối
Startup.cs
using System.Data;
using System.Data.SqlClient;
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
string dbConnectionString = this.Configuration.GetConnectionString("dbConnection1");
services.AddTransient<IDbConnection>((sp) => new SqlConnection(dbConnectionString));
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : IDiameterRepository
{
private readonly IDbConnection _dbConnection;
public DiameterRepository(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return _dbConnection.Query<Diameter>(sql);
}
}
}
Sự cố nếu bạn có nhiều hơn 1 chuỗi kết nối
Kể từ khi Dapper
sử dụngIDbConnection
, bạn cần nghĩ ra cách để phân biệt các kết nối cơ sở dữ liệu khác nhau.
Tôi đã cố gắng tạo nhiều giao diện, được 'kế thừa' từ IDbConnection
, tương ứng với các kết nối cơ sở dữ liệu khác nhau và chèn SqlConnection
các chuỗi kết nối cơ sở dữ liệu khác nhau vào Startup
.
Điều đó không thành công vì SqlConnection
kế thừa từ DbConnection
và DbConnection
inplements không chỉ IDbConnection
mà còn cả Component
lớp. Vì vậy, các giao diện tùy chỉnh của bạn sẽ không thể chỉ sử dụng SqlConnection
implenentation.
Tôi cũng đã cố gắng tạo DbConnection
lớp của riêng mình có chuỗi kết nối khác nhau. Điều đó quá phức tạp vì bạn phải triển khai tất cả các phương thức từ DbConnection
lớp. Bạn đã mất sự giúp đỡ từ SqlConnection
.
Tôi rốt cuộc đang làm gì
- Trong khi đó
Startup
, tôi đã tải tất cả các giá trị chuỗi kết nối vào một từ điển. Tôi cũng tạo một enum
cho tất cả các tên kết nối cơ sở dữ liệu để tránh các chuỗi ma thuật.
- Tôi đã tiêm từ điển là Singleton.
- Thay vì tiêm
IDbConnection
, tôi đã tạo IDbConnectionFactory
và tiêm nó dưới dạng Tạm thời cho tất cả các kho. Bây giờ tất cả các kho lưu trữ IDbConnectionFactory
thay vì IDbConnection
.
- Khi nào chọn kết nối phù hợp? Trong hàm tạo của tất cả các kho! Để làm cho mọi thứ sạch sẽ, tôi đã tạo các lớp cơ sở của kho lưu trữ và để các kho kế thừa từ các lớp cơ sở. Việc lựa chọn chuỗi kết nối phù hợp có thể xảy ra trong các lớp cơ sở.
DatabaseConnectionName.cs
namespace DL.SO.Project.Domain.Repositories
{
public enum DatabaseConnectionName
{
Connection1,
Connection2
}
}
IDbConnectionFactory.cs
using System.Data;
namespace DL.SO.Project.Domain.Repositories
{
public interface IDbConnectionFactory
{
IDbConnection CreateDbConnection(DatabaseConnectionName connectionName);
}
}
DapperDbConenctionFactory - triển khai nhà máy của riêng tôi
namespace DL.SO.Project.Persistence.Dapper
{
public class DapperDbConnectionFactory : IDbConnectionFactory
{
private readonly IDictionary<DatabaseConnectionName, string> _connectionDict;
public DapperDbConnectionFactory(IDictionary<DatabaseConnectionName, string> connectionDict)
{
_connectionDict = connectionDict;
}
public IDbConnection CreateDbConnection(DatabaseConnectionName connectionName)
{
string connectionString = null;
if (_connectDict.TryGetValue(connectionName, out connectionString))
{
return new SqlConnection(connectionString);
}
throw new ArgumentNullException();
}
}
}
Startup.cs
namespace DL.SO.Project.Web.UI
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
var connectionDict = new Dictionary<DatabaseConnectionName, string>
{
{ DatabaseConnectionName.Connection1, this.Configuration.GetConnectionString("dbConnection1") },
{ DatabaseConnectionName.Connection2, this.Configuration.GetConnectionString("dbConnection2") }
};
services.AddSingleton<IDictionary<DatabaseConnectionName, string>>(connectionDict);
services.AddTransient<IDbConnectionFactory, DapperDbConnectionFactory>();
services.AddScoped<IDiameterRepository, DiameterRepository>();
}
}
}
DiameterRepository.cs
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class DiameterRepository : DbConnection1RepositoryBase, IDiameterRepository
{
public DiameterRepository(IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Diameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Diameter>(sql);
}
}
}
DbConnection1RepositoryBase.cs
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection1RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection1RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection1);
}
}
}
Sau đó, đối với các kho lưu trữ khác cần giao tiếp với các kết nối khác, bạn có thể tạo một lớp cơ sở kho lưu trữ khác cho chúng.
using System.Data;
using DL.SO.Project.Domain.Repositories;
namespace DL.SO.Project.Persistence.Dapper
{
public abstract class DbConnection2RepositoryBase
{
public IDbConnection DbConnection { get; private set; }
public DbConnection2RepositoryBase(IDbConnectionFactory dbConnectionFactory)
{
this.DbConnection = dbConnectionFactory.CreateDbConnection(DatabaseConnectionName.Connection2);
}
}
}
using Dapper;
using System.Data;
namespace DL.SO.Project.Persistence.Dapper.Repositories
{
public class ParameterRepository : DbConnection2RepositoryBase, IParameterRepository
{
public ParameterRepository (IDbConnectionFactory dbConnectionFactory)
: base(dbConnectionFactory) { }
public IEnumerable<Parameter> GetAll()
{
const string sql = @"SELECT * FROM TABLE";
return base.DbConnection.Query<Parameter>(sql);
}
}
}
Hy vọng tất cả những sự giúp đỡ.