Получите вызов DbContext в пользовательском классе IDbDependencyResolver для множественного соединения EF6 с разными провайдерами для каждой БД - PullRequest
0 голосов
/ 13 марта 2019

Мне нужен инструмент, который подключается к базе данных MySQL и базе данных MSSQL через EF. У меня есть два отдельных класса DbContext, определенных для каждого соединения, пользовательский класс DbConfiguration для установки поставщиков и пользовательский класс DbDependencyResolver для разрешения каждой службы на основе поставщика, используемого каждым соединением. Соединение работает для каждой базы данных, если метод GetService возвращается на основе сборки, в которой находится каждый пользовательский класс DbContext. У меня есть другая сборка, которая использует оба контекста, и поэтому мне нужен способ определить, какой контекст вызывает метод GetService внутри DbDependencyResolver, чтобы я мог разрешить службу для MSSQL или MySQL.

// SQL Server Context class
[DbConfigurationType(typeof(DbProviderConfig))]
public partial class MSSQLContext : DbContext
{
    public MSSQLContext() : base("name=MSSQLContextConStr")
    {
        this.Configuration.LazyLoadingEnabled = false;

        Database.SetInitializer<MSSQLContext>(null);
        Database.Initialize(false);
    }
}

// MySQL context class
[DbConfigurationType(typeof(DbProviderConfig))]
public partial class MySQLContext : DbContext
{
    public MySQLContext() : base("name=MySQLContextConStr")
    {
        this.Configuration.LazyLoadingEnabled = false;

        Database.SetInitializer<MySQLContext>(null);
        Database.Initialize(false);
    }
}

// DbConfiguration class
public class DbProviderConfig : DbConfiguration
{
    public DbProviderConfig()
    {
        // Main MSSQL database provider and factory
        SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
        SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.SqlConnectionFactory());

        // Secondary MySQL database provider and factory
        SetProviderServices("MySql.Data.MySqlClient", new MySql.Data.MySqlClient.MySqlProviderServices());
        SetProviderFactory("MySql.Data.MySqlClient.MySqlClientFactory", new MySql.Data.MySqlClient.MySqlClientFactory());

        // Custom dependency resolver
        AddDependencyResolver(new DbDependencyResolver());
    }
}

// The custom dependency resolver
public class DbDependencyResolver : IDbDependencyResolver
{
    private readonly System.Reflection.Assembly executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();

    public object GetService(Type type, object key)
    {
        StackTrace stackTrace = new StackTrace();
        StackFrame[] stackFrames = stackTrace.GetFrames().Skip(1).ToArray();
        if (!stackFrames.Any(f => f.GetMethod().DeclaringType.Assembly.Equals(executingAssembly)))
        {
            var resolvedService = new MySqlDependencyResolver().GetService(type, key);
            return resolvedService;
        }
        else
            return null;
    }

    public IEnumerable<object> GetServices(Type type, object key)
    {
        var service = GetService(type, key);
        if (service != null)
        {
            yield return service;
        }
    }
}

Таким образом, мне нужно изменить метод GetService внутри средства разрешения зависимостей, чтобы точно видеть, какой контекст вызывает его, когда я начинаю выполнять операции с коллекциями внутри MSSQLContext и MySQLContext. Пример: простой вызов для подсчета коллекции:

MSSQLContext mssqlContext = new MSSQLContext();
int noOfItems = mssqlContext.Cars.Count(); // where Cars represents all the Car entities inside the SQL Server database of course
...