This database provider allows Entity Framework Core to be used with SQLite. The provider is maintained as part of the Entity Framework Core project.
Supported Database Engines
- SQLite (3.7 onwards)
Supported Platforms
.NET Framework (4.5.1 onwards)
.NET Core
Mono (4.2.0 onwards)
Universal Windows Platform
Getting Started with EF Core on Universal Windows Platform (UWP) with a New Database
Getting Started with EF Core on .NET Core Console App with a New database
SQLite EF Core Database Provider Limitations
ASP.NET Core 开发 – Entity Framework (EF) Core
SQLite has an in-memory mode that allows you to use SQLite to write tests against a relational database, without the overhead of actual database operations.
Example testing scenario
Consider the following service that allows application code to perform some operations related to blogs. Internally it uses a DbContext
that connects to a SQL Server database. It would be useful to swap this context to connect to an in-memory SQLite database so that we can write efficient tests for this service without having to modify the code, or do a lot of work to create a test double of the context.
Get your context ready
Avoid configuring two database providers
In your tests you are going to externally configure the context to use the InMemory provider. If you are configuring a database provider by overriding OnConfiguring
in your context, then you need to add some conditional code to ensure that you only configure the database provider if one has not already been configured.
Tip
If you are using ASP.NET Core, then you should not need this code since your database provider is configured outside of the context (in Startup.cs).
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFProviders.InMemory;Trusted_Connection=True;ConnectRetryCount=0"); } }
Add a constructor for testing
The simplest way to enable testing against a different database is to modify your context to expose a constructor that accepts a DbContextOptions<TContext>
.
public class BloggingContext : DbContext { public BloggingContext() { } public BloggingContext(DbContextOptions<BloggingContext> options) : base(options) { }
DbContextOptions<TContext> tells the context all of its settings, such as which database to connect to. This is the same object that is built by running the OnConfiguring method in your context.
Writing tests
The key to testing with this provider is the ability to tell the context to use SQLite, and control the scope of the in-memory database. The scope of the database is controlled by opening and closing the connection. The database is scoped to the duration that the connection is open. Typically you want a clean database for each test method.
using BusinessLogic; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Linq; namespace TestProject.SQLite { [TestClass] public class BlogServiceTests { [TestMethod] public void Add_writes_to_database() { // In-memory database only exists while the connection is open var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); try { var options = new DbContextOptionsBuilder<BloggingContext>() .UseSqlite(connection) .Options; // Create the schema in the database using (var context = new BloggingContext(options)) { context.Database.EnsureCreated(); } // Run the test against one instance of the context using (var context = new BloggingContext(options)) { var service = new BlogService(context); service.Add("http://sample.com"); } // Use a separate instance of the context to verify correct data was saved to database using (var context = new BloggingContext(options)) { Assert.AreEqual(1, context.Blogs.Count()); Assert.AreEqual("http://sample.com", context.Blogs.Single().Url); } } finally { connection.Close(); } } [TestMethod] public void Find_searches_url() { // In-memory database only exists while the connection is open var connection = new SqliteConnection("DataSource=:memory:"); connection.Open(); try { var options = new DbContextOptionsBuilder<BloggingContext>() .UseSqlite(connection) .Options; // Create the schema in the database using (var context = new BloggingContext(options)) { context.Database.EnsureCreated(); } // Insert seed data into the database using one instance of the context using (var context = new BloggingContext(options)) { context.Blogs.Add(new Blog { Url = "http://sample.com/cats" }); context.Blogs.Add(new Blog { Url = "http://sample.com/catfish" }); context.Blogs.Add(new Blog { Url = "http://sample.com/dogs" }); context.SaveChanges(); } // Use a clean instance of the context to run the test using (var context = new BloggingContext(options)) { var service = new BlogService(context); var result = service.Find("cat"); Assert.AreEqual(2, result.Count()); } } finally { connection.Close(); } } } }
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2015年已经有15个年头,SQLite也迎来了一个版本 SQLite 3已经发布。
不像常见的客户-服务器范例,SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。这在消耗总量、延迟时间和整体简单性上有积极的作用。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。它的简单的设计是通过在开始一个事务的时候锁定整个数据文件而完成的。[1]
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。
为什么要用 SQLite?
不需要一个单独的服务器进程或操作的系统(无服务器的)。
SQLite 不需要配置,这意味着不需要安装或管理。
一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
SQLite 是自给自足的,这意味着不需要任何外部的依赖。
SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。
目前 EF Core 支持的数据库:
- Microsoft SQL Server
- SQLite
- Postgres (Npgsql)
- SQL Server Compact Edition
- InMemory (for testing purposes)
后面将会增加:
- MySQL
- IBM DB2