Помогите подключить EntityFramework к SQLite в Unity

381
16 августа 2021, 01:10

Пытаюсь работать с базой данных SQLite при помощи EntityFramework на Unity. Но получаю исключение:

NotSupportedException: Unable to determine the DbProviderFactory type for connection of type 'System.Data.SQLite.SQLiteConnection'. Make sure that the ADO.NET provider is installed or registered in the application config.
System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver+<>c__DisplayClass5.<GetProviderFactory>b__0 (System.Type t) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].GetOrAdd (TKey key, System.Func`2[T,TResult] valueFactory) (at <f2e6809acb14476a81f399aeb800f8f2>:0)
System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.GetProviderFactory (System.Data.Common.DbConnection connection, System.Collections.Generic.IEnumerable`1[T] dataRows) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.ResolveProviderFactory (System.Data.Common.DbConnection connection) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderFactory (System.Data.Common.DbConnection connection) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Core.Common.DbProviderServices.GetProviderFactory (System.Data.Common.DbConnection connection) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName (System.Data.Common.DbConnection connection) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.InternalConnection.get_ProviderName () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.LazyInternalContext.get_ProviderName () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create (System.Data.Entity.DbContext context) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.LazyInternalContext.InitializeContext () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.InternalContext.Initialize () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType (System.Type entityType) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.Linq.InternalSet`1[TEntity].Initialize () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.Linq.InternalSet`1[TEntity].get_InternalContext () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.Linq.InternalSet`1[TEntity].ActOnSet (System.Action action, System.Data.Entity.EntityState newState, System.Object entity, System.String methodName) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.Internal.Linq.InternalSet`1[TEntity].Add (System.Object entity) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
System.Data.Entity.DbSet`1[TEntity].Add (TEntity entity) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0)
DBConnection.Click () (at Assets/Scripts/PersonalCabinet/DBConnection.cs:21)
UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:36)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:45)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update()

Файл для настройки EntityFramework из кода:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Data.Entity.Infrastructure.DependencyResolution;

class SqliteDbConfiguration : DbConfiguration
{
    public SqliteDbConfiguration()
    {
        string assemblyNameEF6 = typeof(SQLiteProviderFactory).Assembly.GetName().Name;
        RegisterDbProviderFactories<SQLiteProviderFactory>("SQLite Data Provider (Entity Framework 6)", ".NET Framework Data Provider for SQLite (Entity Framework 6)");
        RegisterDbProviderFactories<SQLiteFactory>("SQLite Data Provider", ".NET Framework Data Provider for SQLite");
        SetProviderFactory(assemblyNameEF6, SQLiteFactory.Instance);
        SetProviderFactory(assemblyNameEF6, SQLiteProviderFactory.Instance);
        SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
        DbProviderServices provider = (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices));
        SetProviderServices(assemblyNameEF6, provider);
        SetProviderServices("System.Data.SQLite", provider);
        SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
        SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.LocalDbConnectionFactory("mssqllocaldb"));
        AddDependencyResolver(new SingletonDependencyResolver<DbProviderFactory>(SQLiteProviderFactory.Instance));
    }
    static void RegisterDbProviderFactories<T>(string name, string description)
    {
        string assemblyName = typeof(T).Assembly.GetName().Name;
        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(name, description, assemblyName, typeof(T).AssemblyQualifiedName);

        }
    }
}

Метод Click() класса DBConnection создает контекст базы данных MyDbContext и пытается записать в нее информацию о книге Book. Этот метод назначен на нажатие кнопки и при его выполнении возникает ошибка.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Data.Entity;
using SQLite.CodeFirst;
using System.Configuration;
using System.Data.SQLite;
using System.Data.Common;
public class DBConnection : MonoBehaviour {
    // Use this for initialization
    void Start () {}
    public void Click()
    {
        using (DbConnection connection = new SQLiteConnection("FullUri=file::memory:")) {
            connection.Open();
            using (var db = new MyDbContext(connection)) {
                Book book1 = new Book { Name = "Граф Монтекристо", Price = 123 };
                db.Books.Add(book1);
                db.SaveChanges();
            }
        }
    }
    // Update is called once per frame
    void Update () {}
}
[DbConfigurationType(typeof(SqliteDbConfiguration))]
public class MyDbContext : DbContext
{
    private static readonly ConnectionStringSettings connectionString = new ConnectionStringSettings("localDataBase", "data source=.\\db.bytes", "System.Data.SQLite");
    static MyDbContext()
    {
        ConfigurationManager.ConnectionStrings.Add(connectionString);
        Configuration exeConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        Configuration machineConfig = ConfigurationManager.OpenMachineConfiguration();
    }
    public MyDbContext(DbConnection connection)
        : base(connection, false) {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<MyDbContext>(modelBuilder);
        Database.SetInitializer(sqliteConnectionInitializer);
    }
    public DbSet<Book> Books { get; set; }
}
public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
}
READ ALSO
Отправка ICMP пакетов

Отправка ICMP пакетов

Как отправить ICMP пакет на сервер?

291
Создание нового объекта сущности ADO Model

Создание нового объекта сущности ADO Model

У меня есть база данных SQL с таблицами, я создаю Модель ADONET EDM, получаю всю базу данных в виде сущностей

127
MySQL выборка из двух таблиц

MySQL выборка из двух таблиц

подскажите, как с помощью SQL запроса получить два поля из разных таблиц

241
Сложный UPDATE (MySQL)

Сложный UPDATE (MySQL)

Одним UPDATE надо решить следующую проблему: Если m_bid != 0 - записать это значение в smaxИначе, записать в smax наименьшее из двух значений: m_bid из shops_table,...

208