2016-07-21 2 views
1

Я пытаюсь получить конфигурацию на основе кода EF6 для работы с SQLite в .NET 4.0. В моем целевом приложении App.config автоматически генерируется, поэтому редактирование очень болезненно. Изначально при установке Ef6 в SQLite через NuGet к моему тестовому приложению он генерирует следующую конфигурации, которая работает:EF6 с SQLite в .NET 4.0 Конфигурация на основе кода: «Невозможно определить DbProviderFactory»

<configuration> 
    <configSections> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" /> 
    </startup> 
    <system.data> 
    <DbProviderFactories> 
     <remove invariant="System.Data.SQLite.EF6" /> 
     <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> 
    </DbProviderFactories> 
    </system.data> 
    <entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v11.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
     <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> 
    </providers> 
    </entityFramework> 
</configuration> 

На SQL Server CE я смог просто скопировать содержимое App.config к классу DBConfiguration. Точно так же я попробовал:

class DBConfig : DbConfiguration 
{ 
    public DBConfig() : base() 
    { 
     this.SetDefaultConnectionFactory(new LocalDbConnectionFactory("v11.0")); 

     this.SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance); 
     this.SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance); 

     this.SetProviderServices("System.Data.SqlClient", SqlProviderServices.Instance); 
     this.SetProviderServices("System.Data.SQLite.EF6", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices))); 
    } 
} 

Но при создании контекста, давая конструктор SQLiteConnection или ConnectionString это дает мне System.NotSupportedException:

Невозможно определить тип DbProviderFactory для подключения типа «System. Data.SQLite.SQLiteConnection. Убедитесь, что поставщик ADO.NET установлен или зарегистрирован в конфигурации приложения.

at System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.<>c__DisplayClass5.<GetProviderFactory>b__0(Type t) 
at System.Collections.Concurrent.ConcurrentDictionary'2.GetOrAdd(TKey key, Func'2 valueFactory) 
at System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.GetProviderFactory(DbConnection connection, IEnumerable'1 dataRows) 
at System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.ResolveProviderFactory(DbConnection connection) 
at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderFactory(DbConnection connection) 
at System.Data.Entity.Core.Common.DbProviderServices.GetProviderFactory(DbConnection connection) 
at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName(DbConnection connection) 
at System.Data.Entity.Internal.InternalConnection.get_ProviderName() 
at System.Data.Entity.Internal.LazyInternalContext.get_ProviderName() 
at System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create(DbContext context) 
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
at System.Data.Entity.Internal.InternalContext.Initialize() 
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
at System.Data.Entity.Internal.Linq.InternalSet'1.Initialize() 
at System.Data.Entity.Internal.Linq.InternalSet'1.get_InternalContext() 
at System.Data.Entity.Internal.Linq.InternalSet'1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) 
at System.Data.Entity.Internal.Linq.InternalSet'1.Add(Object entity) 
at System.Data.Entity.DbSet`1.Add(TEntity entity) 

Я попытался:

  • добавления SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
    согласно this answer.
  • добавив AddDependencyResolver(new SingletonDependencyResolver<DbProviderFactory>(SQLiteProviderFactory.Instance));
    и DependencyResolvers для DbProviderServices и IDbConnectionFactory и даже попробовал установить их объявление DefaultResolvers.
  • создание собственного SQLiteConnectionFactory и установка его по умолчанию в соответствии с this answer.

Я помню, что читал где-то, что если есть <System.Data> раздел в файле Machine.config это может привести к путанице в ProviderFactories. Есть ли какая-либо кодовая конфигурация, эквивалентная <remove invariant="" />?

Также класс SQLiteProviderService является внутренним, и единственный способ получить его - отражение в соответствии с this answer. Действительно ли программа имеет доступ к сервису? Это, похоже, работает для большинства людей.

Любая помощь или идеи, чтобы попытаться решить эту проблему!


Любопытное примечание: при создании SQLiteConnection из SQLiteProviderFactory.Instance.CreateConnection() DbProviderFactory свойство соединения является System.Data.SQLite.SQLiteFactory, но с рабочей App.config конфигурации System.Data.Entity.Core.Common.DbProviderServices.GetProviderFactory(connection) возвращает SQLiteProviderFactory. Принимая во внимание, что с кодовой конфигурацией он бросает.

+0

Изменить подключение фабрики по умолчанию быть SQLite? – ErikEJ

+0

Есть ли готовая фабрика соединений? Я не мог найти ни одного, поэтому я создал свой собственный, следуя ответу с одной из ссылок, и установил это как значение по умолчанию. Никакого успеха нет. – Silvyrfir

ответ

0

Here Я нашел предложение, которое помогло мне настроить sqlite с EF6 программно.

Блок кода из этого ответа:

var dataRow = dbProviderFactoriesDataTable.Rows.OfType<DataRow>() 
        .FirstOrDefault(x => x.ItemArray[2].ToString() == assemblyName); 

if (dataRow != null) 
    dbProviderFactoriesDataTable.Rows.Remove(dataRow); 

эквивалентно:

<remove invariant="" /> 
Смежные вопросы