Microsoft.AspNetCore.All : v2.0.3 | Dapper : v1.50.2
Ich bin nicht sicher, ob ich die Best Practices richtig verwende oder nicht, aber ich mache es auf diese Weise, um mehrere Verbindungszeichenfolgen zu verarbeiten .
Es ist einfach, wenn Sie nur 1 Verbindungszeichenfolge haben
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);
}
}
}
Probleme, wenn Sie mehr als eine Verbindungszeichenfolge haben
Da Dapperverwendet wird IDbConnection, müssen Sie sich eine Möglichkeit überlegen , verschiedene Datenbankverbindungen zu unterscheiden.
Ich habe versucht, mehrere Schnittstellen zu erstellen, die von IDbConnectionverschiedenen Datenbankverbindungen "geerbt" wurden , und SqlConnectionverschiedene Datenbankverbindungszeichenfolgen einzuschalten Startup.
Das ist fehlgeschlagen, weil SqlConnectionerbt von DbConnectionund DbConnectionimplementiert nicht nur, IDbConnectionsondern auch ComponentKlasse. Ihre benutzerdefinierten Schnittstellen können also nicht nur die SqlConnectionImplenentation verwenden.
Ich habe auch versucht, eine eigene DbConnectionKlasse zu erstellen , die eine andere Verbindungszeichenfolge verwendet. Das ist zu kompliziert, weil Sie alle Methoden aus der DbConnectionKlasse implementieren müssen . Du hast die Hilfe von verloren SqlConnection.
Was ich am Ende mache
- Währenddessen habe
Startupich alle Verbindungszeichenfolgenwerte in ein Wörterbuch geladen. Ich habe auch einen Namen enumfür alle Datenbankverbindungen erstellt, um magische Zeichenfolgen zu vermeiden.
- Ich habe das Wörterbuch als Singleton injiziert.
- Anstatt zu injizieren
IDbConnection, habe ich IDbConnectionFactorydas als Transient für alle Repositorys erstellt und injiziert. Jetzt nehmen alle Repositories IDbConnectionFactorystatt IDbConnection.
- Wann wählen Sie die richtige Verbindung? Im Konstruktor aller Repositories! Um die Dinge sauber zu machen, habe ich Repository-Basisklassen erstellt und die Repositorys von den Basisklassen erben lassen. Die richtige Auswahl der Verbindungszeichenfolge kann in den Basisklassen erfolgen.
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 - meine eigene Factory-Implementierung
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);
}
}
}
Für andere Repositorys, die mit den anderen Verbindungen kommunizieren müssen, können Sie dann eine andere Repository-Basisklasse für diese erstellen.
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);
}
}
}
Hoffe all diese Hilfe.