【问题标题】:Cannot configure Entity Framework for SQLite in Unity无法在 Unity 中为 SQLite 配置实体框架
【发布时间】:2020-01-28 13:52:35
【问题描述】:

我想在 Unity 中使用使用实体框架的 SQLite 数据库。但是在运行时出现错误:

NotSupportedException:无法确定类型为“System.Data.SQLite.SQLiteConnection”的连接的 DbProviderFactory 类型。确保在应用程序配置中安装或注册了 ADO.NET 提供程序。

这是我的实体框架配置:

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);
        }
    }
}

DBConnection 类的Click() 方法创建MyDbContext 的数据库上下文,并尝试将有关Book 的信息写入其中。这个方法被赋值给一个按钮的点击,执行的时候会报错(在这一行:

db.Books.Add(book1);

完整代码:

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; }
}

执行DBConnection.Click() 时发生异常:

NotSupportedException:无法确定类型为“System.Data.SQLite.SQLiteConnection”的连接的 DbProviderFactory 类型。确保在应用程序配置中安装或注册了 ADO.NET 提供程序。

System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver+c__DisplayClass5.b__0 (System.Type t) (at :0)

System.Collections.Concurrent.ConcurrentDictionary2[TKey,TValue].GetOrAdd (TKey key, System.Func2[T,TResult] valueFactory) (at :0)

System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.GetProviderFactory(System.Data.Common.DbConnection 连接,System.Collections.Generic.IEnumerable`1[T] dataRows)(在:0)

System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.ResolveProviderFactory(System.Data.Common.DbConnection 连接)(在:0)

System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderFactory(System.Data.Common.DbConnection 连接)(在:0)

System.Data.Entity.Core.Common.DbProviderServices.GetProviderFactory(System.Data.Common.DbConnection 连接)(在:0)

System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName(System.Data.Common.DbConnection 连接)(在:0) System.Data.Entity.Internal.InternalConnection.get_ProviderName () (在:0) System.Data.Entity.Internal.LazyInternalContext.get_ProviderName () (at :0) System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create(System.Data.Entity.DbContext 上下文)(在:0) System.Data.Entity.Internal.LazyInternalContext.InitializeContext () (at :0) System.Data.Entity.Internal.InternalContext.Initialize () (at :0) System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType (System.Type entityType) (at :0) System.Data.Entity.Internal.Linq.InternalSet1[TEntity].Initialize () (at <f8fadb18f6a84dcf8e300a2f11995d19>:0) System.Data.Entity.Internal.Linq.InternalSet1[TEntity].get_InternalContext () (at :0) System.Data.Entity.Internal.Linq.InternalSet1[TEntity].ActOnSet (System.Action action, System.Data.Entity.EntityState newState, System.Object entity, System.String methodName) (at <f8fadb18f6a84dcf8e300a2f11995d19>:0) System.Data.Entity.Internal.Linq.InternalSet1[TEntity].Add(System.Object 实体)(在:0) System.Data.Entity.DbSet1[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+EventFunction1[T1] 函子)(在 C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261) UnityEngine.EventSystems.EventSystem:Update()

【问题讨论】:

    标签: c# entity-framework sqlite unity3d


    【解决方案1】:

    使用 Entity FrameWork Core(用于跨平台)而不是使用 Entity FrameWork(不支持 .NET Core)进行统一项目;还要确保统一 api 级别是 .net standard 2.0

    【讨论】:

      猜你喜欢
      • 2015-08-12
      • 2017-12-11
      • 2013-04-13
      • 2010-10-30
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 2011-08-23
      • 2012-11-28
      相关资源
      最近更新 更多