SQLite Entity Framework без App.config

3

Необходимо использовать SQLite Entity Framework Database - первый подход для плагина приложения 3d-party. Я искал весь Интернет, включая Добавить DbProviderFactory без App.Config, Проблемы с использованием Entity Framework 6 и SQLite и многие другие. Я попытался использовать их все разными способами и комбинациями, но ничего не помогает:

"Необработанное исключение типа В файле mscorlib.dll произошел" System.Data.Entity.Core.MetadataException ". Дополнительная информация: Указанная схема недействительна. Ошибки: AutosuggestModel.ssdl(2,2): ошибка 0152: поставщик Entity Framework отсутствует найдено для поставщика ADO.NET с именем инварианта 'System.Data.SQLite.EF6. Убедитесь, что поставщик зарегистрирован в раздел" entityFramework "файла конфигурации приложения."

В решении есть тестовое консольное приложение. С помощью этого минимального App.config он работает:

<?xml version="1.0" encoding="utf-8"?>
<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>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>

Строка подключения уже реализована в коде. Используемые пакеты:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net452" />
  <package id="System.Data.SQLite" version="1.0.98.1" targetFramework="net452" />
  <package id="System.Data.SQLite.Core" version="1.0.98.1" targetFramework="net452" />
  <package id="System.Data.SQLite.EF6" version="1.0.98.1" targetFramework="net452" />
  <package id="System.Data.SQLite.Linq" version="1.0.98.1" targetFramework="net452" />
</packages>

Пожалуйста, укажите весь необходимый код и укажите, куда его вставить. Спасибо заранее.

  • 0
    проблема с sqlite и EF заключается в том, что инициализаторы базы данных не работают правильно, потому что Create database и Create table не поддерживаются в пакете (по крайней мере, версии, с которыми я работал). Ваш код кажется довольно странным. сначала вы определяете инвариант System.Data.SQLite.EF6, а затем уже не используете его. Ваша проблема не связана с провайдером, а связана с кодом. попробуйте переименовать инвариант в DbProviderFactories в «System.Data.SQLite.EF6», но, возможно, есть и другие ошибки, которые я здесь пропускаю.
  • 0
    Спасибо, но с таким App.config все работает правильно, а база данных у меня уже есть. Мне нужно, чтобы приложение работало без App.сonfig. С помощью ответов по ссылкам выше раздел «system.data» можно удалить, но другие разделы все же необходимы.
Показать ещё 2 комментария
Теги:
entity-framework
app-config

1 ответ

3
Лучший ответ

Вот пример кода, который иллюстрирует, как достичь цели.

namespace SqliteEFNoConfig
{
    using System.Configuration;
    using System.Data;
    using System.Data.Common;
    using System.Data.Entity;
    using System.Data.Entity.Core.Common;
    using System.Data.SQLite;
    using System.Data.SQLite.EF6;
    using System.Linq;

    internal class Program
    {
        private static void Main()
        {
            // EF manages the connection via the DbContext instantiation
            // connection string is set in config
            // Use this code if you want to use a config file
            // with only the connection string
            //using (var model = new Model1())
            //{
            //    var dbSetProperty = model.dbSetProperty.ToList();
            //}

            // Alternative method: 
            // Use this code if you don't want to use a config file
            // You will also need to use the override constructor shown below,
            // in your EF Model class
            var connectionString = @"data source = {PathToSqliteDB}";
            using (var connection = new SQLiteConnection(connectionString))
            {
                using (var model = new Model1(connection))
                {
                    var dbSetProperty = model.dbSetProperty.ToList();
                }
            }
        }
    }

    class SqliteDbConfiguration : DbConfiguration
    {
        public SqliteDbConfiguration()
        {
            string assemblyName = typeof (SQLiteProviderFactory).Assembly.GetName().Name;

            RegisterDbProviderFactories(assemblyName );
            SetProviderFactory(assemblyName, SQLiteFactory.Instance);
            SetProviderFactory(assemblyName, SQLiteProviderFactory.Instance);
            SetProviderServices(assemblyName,
                (DbProviderServices) SQLiteProviderFactory.Instance.GetService(
                    typeof (DbProviderServices)));
        }

        static void RegisterDbProviderFactories(string assemblyName)
        {
            var dataSet = ConfigurationManager.GetSection("system.data") as DataSet;
            if (dataSet != null)
            {
                var dbProviderFactoriesDataTable = dataSet.Tables.OfType<DataTable>()
                    .First(x => x.TableName == typeof (DbProviderFactories).Name);

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

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

                dbProviderFactoriesDataTable.Rows.Add(
                    "SQLite Data Provider (Entity Framework 6)",
                    ".NET Framework Data Provider for SQLite (Entity Framework 6)",
                    assemblyName,
                    typeof (SQLiteProviderFactory).AssemblyQualifiedName
                    );
            }
        }
    }
}

Если вы решите не добавить строку подключения в файл конфигурации, вам нужно добавить следующий конструктор в EF-модель.

public Model1(DbConnection connection)
    : base(connection, true)
{
}

Примечание:. Вышеприведенный код - это всего лишь образец того, как достичь цели, и вам придется приспособить его в соответствии с вашими потребностями. Приведенный выше код предоставляется при условии, что вы используете подход EF Code First.

  • 0
    Извините, но это не работает.
  • 0
    Это не работает из коробки. Вы должны настроить его под свой код. По этой причине я специально добавил раздел «Уведомление».
Показать ещё 14 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню