您现在的位置是:首页 > 文章详情

【C#】使用EF访问Sqlite数据库

日期:2018-05-25点击:558
原文: 【C#】使用EF访问Sqlite数据库

1. 先上Nuget下载对应的包

这里写图片描述
如图,搜索System.Data.SQLite下载安装即可,下载完之后带上依赖一共有这么几个:

  1. EntityFramework
  2. System.Data.SQLite
  3. System.Data.SQLite.Core
  4. System.Data.SQLite.EF6
  5. System.Data.SQLite.Linq

安装完成后,会添加App.config文件(如果没有的话),里面添加了一些provider的配置。

2. 先看下DB First模式

如果你用的是VS2017的话,很不幸无法通过“ADO.NET实体数据模型”来生成edmx文件。如果用VS2015及之前版本的话可以去官网下载一个插件,安装之后就可以用了。这里以VS2017为例:
1. 首先,在App.config中配置数据库连接字符串:

<connectionStrings> <add name="SqliteTest" connectionString="Data Source=E:\retail.db" providerName="System.Data.SQLite.EF6" /> </connectionStrings>

2.然后就可以 编写数据库上下文和实体了,然后就可以用了

public class RetailContext : DbContext { public RetailContext(): base("SqliteTest"){} public DbSet<Thumbnail> Thumbnails { set; get; } } public class Thumbnail { public Int64 Id { get; set; } [Required] [Unique] public string OrginFilePath { get; set; } [Required] public string ThumbnailPath { get; set; } [Required] public DateTime LastUpdateTime { get; set; } }

不过在运行过程中你可能会遇到这个错误SQLite error of “Unable to find the requested .Net Framework Data Provider.
解决方法就是在App.config的providers中添加以下节点

<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />

完整的如下:

 <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" /> <!-- 1. Solves SQLite error of "Unable to find the requested .Net Framework Data Provider."--> <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> </providers>

从上面的代码可以看到数据库的路径是写死的不能改变,这样就很不灵活。我喜欢可以动态连接的数据库,所以再次修改:
我们知道DbContext这个类有几个构造函数,一个是接收string类型的connectionString,一般都用的是这个。还有一个构造函数是接收一个DbConnection类型参数和bool类型的参数。这个构造函数就可以实现我们的要求:

  • 首先,构造一个DbConnection类:
    DbConnection sqliteCon = SQLiteProviderFactory.Instance.CreateConnection();
  • 然后,给这个对象设置ConnectionString
    sqliteCon.ConnectionString = dbPath;
  • 最后,把这个对象传给DbContext即可。

    如下:

public class ThumbnailContext : DbContext { static string dbPath = $"Data Source=E:\\thumbnail.db"; public static ThumbnailContext Instance { get { DbConnection sqliteCon = SQLiteProviderFactory.Instance.CreateConnection(); sqliteCon.ConnectionString = dbPath; return new ThumbnailContext(sqliteCon); } } private ThumbnailContext(DbConnection con) : base(con, true) { } public DbSet<Thumbnail> Thumbnails { get; set; } }

3. CodeFirst模式

Sqlite默认不支持CodeFirst模式,如果用户因为某些操作删除了我们的db文件,此时我们的程序就不能正常工作了,是不是有点尴尬?不过还是有解决办法的,在Nuget里搜索SQLite.CodeFirst安装即可。
这里写图片描述
然后重写DbContextOnModelCreating方法。这里是修改后的数据库上下文:

 public class ThumbnailContext : DbContext { static string dbPath = $"Data Source={PathManager.AppDataTempThumbnail}\\thumbnail.db"; public static ThumbnailContext Instance { get { DbConnection sqliteCon = SQLiteProviderFactory.Instance.CreateConnection(); sqliteCon.ConnectionString = dbPath; return new ThumbnailContext(sqliteCon); } } private ThumbnailContext(DbConnection con) : base(con, true) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //如果不存在数据库,则创建 Database.SetInitializer(new SqliteCreateDatabaseIfNotExists<ThumbnailContext>(modelBuilder)); } public DbSet<Thumbnail> Thumbnails { get; set; } }

4.一些优化

在使用过程中你可能会察觉到,每当第一次访问数据库(查询、插入等)时总是会慢一点,可能有1秒的时间数据库才会做出响应,然后接下再操作就很快。
这是因为当你第一次访问数据库时,EF需要在内存中建立实体与数据库表的映射关系,这个操作需要点时间。所以在你的程序一启动的时候就要把关系给映射好。
这里以上面的ThumbnailContext为例,首先new一个对象,假设为dbContext。然后在你整个应用程序的入口点调用下述代码:

public void Init() { //Pre-Generated Mapping Views var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace); mappingCollection.GenerateViews(new List<EdmSchemaError>()); }

后记:通过EF来访问Sqlite数据库,我也使用了有一段时间了,但是有时候会出现几个莫名奇妙的问题,而且还不太好定位,不知道是不是EF和Sqlite不太兼容的问题。现在尝试改为用ADO.NET来访问,于是就有了接下来的这篇文章:【C#】使用ADO.NET访问Sqlite数据库,SqliteHelper帮助类


参考链接:

1. Sqlite3+EF6踩的坑
2. 让EntityFramework6支持SQLite

原文链接:https://yq.aliyun.com/articles/678526
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章