I want to use a SQLite database using Entity Framework in Unity. But at runtime an error occurs:
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.
This is my Entity Framework configuration:
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);
}
}
}
The Click() method of the DBConnection class creates the database context of MyDbContext and tries to write information about the Book to it. This method is assigned to the click of a button and an error occurs when it is executed (on this line:
db.Books.Add(book1);
Complete code:
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; }
}
Exception occurred while DBConnection.Click() was executed:
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.b__0 (System.Type t) (at :0)
System.Collections.Concurrent.ConcurrentDictionary
2[TKey,TValue].GetOrAdd (TKey key, System.Func2[T,TResult] valueFactory) (at :0)System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.GetProviderFactory (System.Data.Common.DbConnection connection, System.Collections.Generic.IEnumerable`1[T] dataRows) (at :0)
System.Data.Entity.Infrastructure.Net40DefaultDbProviderFactoryResolver.ResolveProviderFactory (System.Data.Common.DbConnection connection) (at :0)
System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderFactory (System.Data.Common.DbConnection connection) (at :0)
System.Data.Entity.Core.Common.DbProviderServices.GetProviderFactory (System.Data.Common.DbConnection connection) (at :0)
System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInvariantName (System.Data.Common.DbConnection connection) (at :0) System.Data.Entity.Internal.InternalConnection.get_ProviderName () (at :0) System.Data.Entity.Internal.LazyInternalContext.get_ProviderName () (at :0) System.Data.Entity.Internal.DefaultModelCacheKeyFactory.Create (System.Data.Entity.DbContext context) (at :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.InternalSet
1[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 entity) (at :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] functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261) UnityEngine.EventSystems.EventSystem:Update()