c# - studio - Problemas al usar Entity Framework 6 y SQLite
sqlite visual studio 2015 (4)
Estoy intentando usar Entity Framework con SQLite. Tuve problemas para integrarlo en mi aplicación principal, así que comencé una pequeña prueba desde cero, siguiendo exactamente las instrucciones en http://brice-lambson.blogspot.com/2012/10/entity-framework-on-sqlite.html
Después de todo lo dicho y hecho, aparece el siguiente error al ejecutar el proyecto:
No se ha encontrado ningún proveedor de Entity Framework para el proveedor ADO.NET con el nombre invariable ''System.Data.SQLite''. Asegúrese de que el proveedor esté registrado en la sección ''entityFramework'' del archivo de configuración de la aplicación. Consulte http://go.microsoft.com/fwlink/?LinkId=260882 para obtener más información.
Mi app.config se ve así:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLite Data Provider"
invariant="System.Data.SQLite"
description="Data Provider for SQLite"
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="ChinookContext"
connectionString=
"Data Source=|DataDirectory|Chinook_Sqlite_AutoIncrementPKs.sqlite"
providerName="System.Data.SQLite" />
</connectionStrings>
</configuration>
Luego vi su publicación sobre Entity Framework 6. Si bien no era el error exacto que estaba obteniendo, intenté instalar su proveedor actualizado a través de NuGet. El error desapareció, pero se reemplazó por este:
No se pudo cargar el archivo o ensamblado ''System.Data.SQLite.Linq, Version = 2.0.88.0, Culture = neutral, PublicKeyToken = db937bc2d44ff139'' o una de sus dependencias. La definición del manifiesto del ensamblaje ubicado no coincide con la referencia de ensamblaje. (Excepción de HRESULT: 0x80131040)
Además, mi app.config cambió (ligeramente) a esto:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq, Version=2.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description="Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
<remove invariant="System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="ChinookContext" connectionString="Data Source=|DataDirectory|Chinook_Sqlite_AutoIncrementPKs.sqlite" providerName="System.Data.SQLite" />
</connectionStrings>
</configuration>
He intentado todo lo que se me ocurre para solucionar estos errores, nada ha funcionado. He intentado usar los otros binarios de SQLite; Intenté editar manualmente el proyecto SQLite para usar la versión EF 6; Cambié las arquitecturas, agregué y eliminé los paquetes nuget una y otra vez, etc.
No tengo ni idea de dónde ir desde aquí.
Con base en el comentario de magicandre1981, comencé a mirar más de cerca la sintaxis del nodo proveedor. Descubrí que mi ensamblaje era una versión diferente a la especificada en el atributo de tipo, aunque no había insertado ni tocado esa línea en particular. Al eliminar la fuerte denominación, obtuve .Net para cargar la biblioteca. Como referencia, aquí está la nueva línea:
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq" />
Eso me volvió a encarrilar y pude hacer coincidir mis resultados con los del blog.
Sin embargo, me siento obligado a señalar que he decidido que SQLite no es una buena opción para Entity Framework, ya que faltan demasiadas funciones críticas. Cambié a SQL Server Compact Edition, que instalé a través de NuGet. Un simple ajuste a mi Connection String y me estaba ejecutando con todo el poder de Entity Framework. Tardó menos de un minuto, en comparación con el slog de varias horas que era SQLite. Recomiendo cambiar las bases de datos si es posible, System.Data.SQLite simplemente no está listo para Entity Framework.
Para cualquiera que use la configuración basada en código y aún reciba la misma excepción: necesitaba configurar adicionalmente la fábrica de conexiones en la respuesta de kjbartel.
public class SQLiteConnectionFactory : IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
return new SQLiteConnection(nameOrConnectionString);
}
}
A continuación, establezca la fábrica de conexiones predeterminada en SQLiteConfiguration
public class SQLiteConfiguration : DbConfiguration
{
public SQLiteConfiguration()
{
SetDefaultConnectionFactory(new SQLiteConnectionFactory());
SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
Type t = Type.GetType( "System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6");
FieldInfo fi = t.GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static);
SetProviderServices("System.Data.SQLite", (DbProviderServices)fi.GetValue(null));
}
}
Sé que esta es una vieja pregunta, pero nadie parece haber proporcionado una respuesta que realmente utiliza el archivo .config. Aquí están las secciones system.data y entityframework de mi web.config que permite las conexiones a las bases de datos SQL Server y Sqlite:
<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" />
<remove invariant="System.Data.SQLite" />
<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>
<entityFramework>
<providers>
<provider invariantName="System.Data.SQLite.EF6"
type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite"
type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
Solo pensé en compartir otra forma de configurar EF6 con SQLite sin usar app.config
/ web.config
. EF6 ahora admite configuraciones basadas en código como se describe aquí en msdn . Utilicé el siguiente código (actualizado para eliminar la reflexión gracias a Sly):
public class SQLiteConfiguration : DbConfiguration
{
public SQLiteConfiguration()
{
SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
}
}
Utilizo esto para poder inyectar el DbContext
correcto y, por DbProvider
tanto, DbProvider
en tiempo de ejecución y no necesito todo lo configurado en el ensamblaje principal.
Editar:
Como dijo Reyn , también necesitarás agregar un IDbConnectionFactory
para SQLite si deseas tener tu cadena de conexión en tu web.config
/ app.config
. Otro enfoque es llamar a un constructor base diferente desde su DbContext
que pasa una nueva SQLiteConnection
lugar de la cadena de conexión, como se muestra en esta respuesta .