Я использую: EF 6.2, VisualStudio 2017, nUnit 2.6.3.13283 (модульный тест), Unity 5.8.5 (как IoC).
Проблема появляется, когда я хочудля проверки двух разных DbContexts в одном и том же UnitTest.
Первый контекст:
public class MsSqlConfiguration : System.Data.Entity.DbConfiguration
{
public MsSqlConfiguration()
{
this.SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.SqlConnectionFactory());
this.SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
}
}
[DbConfigurationType(typeof(MsSqlConfiguration))]
public class SqlDbContext: DbContext
{
public SqlDbContext(string connectonString) : base(connectonString)
{}
public DbSet<SomeClass> SomeField { get; set; }
}
Второй контекст:
public class SQLiteProviderInvariantName : IProviderInvariantName
{
public static readonly SQLiteProviderInvariantName Instance = new SQLiteProviderInvariantName();
private SQLiteProviderInvariantName() { }
public const string ProviderName = "System.Data.SQLite.EF6";
public string Name { get { return ProviderName; } }
}
class SQLiteDbDependencyResolver : IDbDependencyResolver
{
public object GetService(Type type, object key)
{
if (type == typeof(IProviderInvariantName)) return SQLiteProviderInvariantName.Instance;
if (type == typeof(DbProviderFactory)) return SQLiteProviderFactory.Instance;
return SQLiteProviderFactory.Instance.GetService(type);
}
public IEnumerable<object> GetServices(Type type, object key)
{
var service = GetService(type, key);
if (service != null) yield return service;
}
}
public class SQLiteConfiguration : System.Data.Entity.DbConfiguration
{
public SQLiteConfiguration()
{
AddDependencyResolver(new SQLiteDbDependencyResolver());
SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
}
}
[DbConfigurationType(typeof(SQLiteConfiguration))]
public class SqlDbContext : DbContext
{
public SqlDbContext (string connectonString) : base(connectonString)
{
}
public DbSet<SomeClass> SomeField{ get; set; }
}
UnitTest:
[TestFixture]
class DbContextIntegrationTests
{
[Test]
public void CanReadFromMsSqlDatabase()
{
using (var context = IocContainer.Instance.Resolve<MsSqlDbContext>(someConnString))
{
Assert.DoesNotThrow(() => context.SomeField.FirstOrDefault());
}
}
[Test]
public void CanReadFromSqliteDatabase()
{
using (var context2 = IocContainer.Instance.Resolve<SqliteDbContext>(someConnString2))
{
Assert.DoesNotThrow(() => context2.Somefield.FirstOrDefault());
}
}
}
Когда я создаю экземпляр вышеупомянутого контекста отдельно, передавая строку подключения - они оба работают нормально.
Однако, если они являются частьютот же класс модульного тестирования - они не могут быть запущены.Первый контекст устанавливает своего провайдера по умолчанию (скажем, для SQL), а следующий DbContext (скажем, для SQLite) не может установить его провайдера.
Если MS SQL dbcontext идет первым, то SQLite dbcontext получает следующее исключение:
System.InvalidOperationException: 'Невозможно завершить операцию.Предоставленный SqlConnection не указывает начальный каталог или AttachDBFileName. '
Если SQLite идет первым, тогда контекст MS SQL получает:
System.InvalidOperationException:' Тип хранилища'date' не найден в манифесте поставщика SQLite '
Мне просто интересно, что мне здесь не хватает.Будь то nUnit специфично (какой-то кеш).Или это действительно обычное место для провайдеров EF, которое можно установить только один раз.
Я вообще не использую App.config - просто передаю строку конфигурации из некоторого сохраненного места.