Подтвердить что ты не робот

EF6 и несколько конфигураций (SQL Server и SQL Server Compact)

Обновление: Проблема решена, см. конец этого вопроса.

Проблема:

Мы пытаемся использовать Entity Framework 6 и конфигурацию на основе кода в сценарии: мы использовали SQL Server и SQL Server CE в том же AppDomain.

Этот довольно простой сценарий, похоже, не поддерживается "по дизайну". От команды EF:

Примечание. Мы не поддерживаем наличие нескольких классов конфигурации, используемых в тот же AppDomain. Если вы используете этот атрибут для установки разных классов конфигурации для двух контекстов, будет выбрано исключение.

Дополнительная информация здесь: Конфигурация на основе кода (Codeplex)

Вопрос:

Как нам двигаться дальше? Любая помощь будет принята с благодарностью! Существует ли более гибкий способ подключения конфигурации к контексту вместо AppDomain?

(Наши классы контекста расположены в разных сборках. Мы попробовали атрибут DbConfigurationType, но проблема в самом EF)

Конфигурационные файлы:

Конфигурация для обычного SQL-сервера

public class EfConfiguration : DbConfiguration
{
    public EfConfiguration()
    {
        SetProviderServices(
            SqlProviderServices.ProviderInvariantName, 
            SqlProviderServices.Instance);

        SetDefaultConnectionFactory(new SqlConnectionFactory());
    }
}

Конфигурация для SQL Server Compact Edition

public class EfCeConfiguration : DbConfiguration
{
    public EfCeConfiguration()
    {
        SetProviderServices(
            SqlCeProviderServices.ProviderInvariantName,
            SqlCeProviderServices.Instance);

        SetDefaultConnectionFactory(
            new SqlCeConnectionFactory(SqlCeProviderServices.ProviderInvariantName));
    }
}

UPDATE:

Ошибка, которую мы получаем:

System.TypeInitializationException: инициализатор типа для 'MyProject.Repositories.Base.DataContext' бросил исключение. ---- > System.InvalidOperationException: экземпляр "EfCeConfiguration" был установлен, но этот тип не был обнаружен в той же сборке, что и контекст DataContext. Или поместите тип DbConfiguration в ту же сборку, что и DbContext введите DbConfigurationTypeAttribute в тип DbContext, чтобы укажите тип DbConfiguration или задайте тип DbConfiguration в файл конфигурации. См. http://go.microsoft.com/fwlink/?LinkId=260883 для Дополнительная информация.

UPDATE 2, решение Как описано выше, мы можем иметь только одну конфигурацию. Это проблема, поскольку Sql и SqlCe использует разные поставщики. Если мы используем "SetDefaultConnectionFactory" для соответствия одному типу базы данных, другой будет терпеть неудачу.

Вместо этого поставьте соединение в контекст, как описано в сообщении, помеченном как ответ ниже. Как только вы всегда инициализируете контекст с помощью соединения, в отличие от строки соединения, вам хорошо идти. Вы можете удалить вызов SetDefaultConnectionFactory из конфигурации. Мы используем только код ниже для настройки контекста SqlCe и без конфигурации для контекста Sql.

  public class CommonEfConfiguration : DbConfiguration
    {
        public CommonEfConfiguration()
        {
            // EF does not know if the ce provider by default,
            // therefore it is required to be informed about it.
            // The connection factories are not necessary since the connection
            // is always created in the UnitOfWork classes
            SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance);
        }
    }
4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ: на основе данных об ошибке: Вы уже пытались сказать EF, где найден класс конфигурации?

[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssemblyFullyQualifiedName")]
public class MyContextContext : DbContext
{
}

Если это невозможно сделать, см. альтернативный

Использовать контекст с конструктором DbConnection

public class MYDbContext : DbContext {
     // MIgration parameterless constructor is managed in  MyMigrationsContextFactory 

    public MyDbContext(string connectionName) : base(connectionName) { } // no this

    public MYDbContext(DbConnection dbConnection, bool contextOwnsConnection)  // THIS ONE
        : base(dbConnection, contextOwnsConnection) {  }

вам потребуется соединение "DBConnection" для каждого провайдера. Для сервера SQL

      public DbConnection GetSqlConn4DbName(string dataSource, string dbName) {
        var sqlConnStringBuilder = new SqlConnectionStringBuilder();
        sqlConnStringBuilder.DataSource = String.IsNullOrEmpty(dataSource) ? DefaultDataSource : dataSource;
        sqlConnStringBuilder.IntegratedSecurity = true;
        sqlConnStringBuilder.MultipleActiveResultSets = true;

        var sqlConnFact = new SqlConnectionFactory(sqlConnStringBuilder.ConnectionString);
        var sqlConn = sqlConnFact.CreateConnection(dbName);
        return sqlConn;
    }

repeat для SqlCe factory, он также может генерировать DBConnection           Фактор соединения SqlCe создает соединение

Ответ 2

что я сделал:

public partial class MyDataBaseContext : DbContext
{
    public MyDataBaseContext (string ConnectionString)
        : base(ConnectionString)
    {
    }
}

Ответ 3

Я нашел решение в сообщение на форуме в форуме.

В принципе, у меня было два проекта, каждый из которых имел свой собственный контекст. Entity Framework загружал только (первый) один из классов DbConfiguration и пытался использовать эту же конфигурацию для обоих проектов. Это причина, по которой сообщение об ошибке говорит что-то вроде

"Был установлен экземпляр" EfCeConfiguration ", но этот тип не был обнаружен в той же сборке, что и контекст" DataContext ".

Итак, как кто-то предложил в что сообщение в форуме Microsoft, я удалил все тега [DbConfigurationType(typeof(DbConfigurationClass))] из классов, которые наследуют от DbContext в обоих проектов, и ошибка больше не повторялась.