使用 System.Data.SQLite 和 Entity Framework 6 的简单示例
Posted
技术标签:
【中文标题】使用 System.Data.SQLite 和 Entity Framework 6 的简单示例【英文标题】:Simple example using System.Data.SQLite with Entity Framework 6 【发布时间】:2016-07-24 21:49:06 【问题描述】:我正在尝试使用 SQLite 和 EF6 在控制台应用程序中获取一个简单的代码第一个示例,但是我遇到了多个错误: 我在 VS 2015 中创建了一个新的控制台项目。 然后通过 NuGet 安装 EF (6.1.3) 和 System.Data.SQLite (1.0.102)。
尝试运行一个简单的程序:
namespace SQLiteConsole1
class Person
public int Id get; set;
public string Name get; set;
class MyContext : DbContext
public DbSet<Person> Persons get; set;
class Program
static void Main(string[] args)
using (var db = new MyContext())
var person = new Person() Name = "John" ;
db.Persons.Add(person);
db.SaveChanges();
这就是我的 App.Config 的样子:
<connectionStrings>
<add name="MyContext" connectionString="Data Source=C:\Temp\Test.sqlite" providerName="System.Data.SQLite" />
</connectionStrings>
<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.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<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>
当我第一次运行这个程序时,我收到以下错误:
未处理的异常:System.InvalidOperationException:没有实体框架 为具有不变名称的 ADO.NET 提供程序找到了提供程序 'System.Data.SQLite'。确保提供程序已在 应用程序配置文件的“entityFramework”部分。”
所以我将<provider invariantName="System.Data.SQLite.EF6"
更改为<provider invariantName="System.Data.SQLite"
,然后我得到这个错误:
未处理的异常: System.Data.Entity.Infrastructure.DbUpdateException:发生错误 在更新条目时。有关详细信息,请参阅内部异常。 System.Data.Entity.Core.UpdateException:发生错误时 更新条目。有关详细信息,请参阅内部异常。 System.Data.SQLite.SQLiteException:SQL 逻辑错误或缺失 数据库没有这样的表:人
要使这个简单的示例正常工作,需要进行哪些更改?
【问题讨论】:
【参考方案1】:这里问了一个类似的问题: Entity Framework 6 with SQLite 3 Code First - Won't create tables
kjbartel 给出了非常有用的解释,即 EF SQLite 驱动程序不支持创建表。
另请参阅https://github.com/msallin/SQLiteCodeFirst,它提供了出色的解决方案。我安装了 SQLite.CodeFirst NuGet 包,并添加了以下代码,然后应用程序运行正常:
class MyContext : DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<MyContext>(modelBuilder);
Database.SetInitializer(sqliteConnectionInitializer);
public DbSet<Person> Persons get; set;
【讨论】:
这里有什么特别要注意的吗?我有一个连接字符串定义为 并在我的 OnModelCreating 中有以下内容,但我收到一个错误“底层提供程序在打开时失败”:var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<add name="MyContext" connectionString="Data Source=.\TestDB.sqlite" providerName="System.Data.SQLite" />
。这有什么不同吗?
不,使用相对路径与绝对路径似乎不是问题。
我明白了。我的问题最终是我只使用连接字符串创建上下文,但没有提供程序。我只需要使用连接字符串的名称而不是实际的连接字符串。
这是否也支持延迟加载和急切加载?【参考方案2】:
您需要使用模型表初始化数据库。注意错误“SQL 逻辑错误或缺少数据库没有这样的表:人”。
这意味着您需要运行 SQL 来在数据库中创建相应的表,幸运的是,如果使用 VS,在模型编辑器(*.edmx 文件)中的上下文菜单下,有一个选项可以让它自动-生成 SQL 并执行它以根据模型在数据库中为您创建表条目。注意:有时为非 MS-SQL 自动生成的问题可能需要在编译/运行之前手动修复。
【讨论】:
我的理解是EF Code First应该自动生成所有表。这是 ORM 的主要目的之一...... AFAIK,唯一完全自动生成的是客户端 C# 模型类,这些定义可以从较新的数据库模型中快速更新(例如,添加到表中的列),但反过来(Model -> DB Layout)只会生成一个完整的 DDL DROP/CREATE 文件。 你是在说 SQLite 还是任何 Code First?以上是关于使用 System.Data.SQLite 和 Entity Framework 6 的简单示例的主要内容,如果未能解决你的问题,请参考以下文章
无法在 System.Data.SQLite 中使用 REGEXP 运算符
使用 System.Data.SQLite (C#) 的 SQLite 查询比在 SQLiteStudio 中要慢得多
C# 引入Sqlite 未能加载文件或程序集“System.Data.SQLite
Windows Mobile 6.1 + SQLite:无法加载类型“System.Data.SQLite.SQLiteConnection”