简体   繁体   English

如何使用 Entity Framework Core 为 sqlite 编写代码第一个单元测试?

[英]How to write code first unit test for sqlite using Entitity Framework Core?

I'm trying to do a very simple rest api for starters.我正在尝试为初学者做一个非常简单的 rest api。 I created the local sqlite file using the tool and it works.我使用该工具创建了本地 sqlite 文件,它可以工作。 Now I want to write a unit test for the database.现在我想为数据库编写一个单元测试。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace dz1
{
    [Table("User")]
    public class User
    {
        [Key]
        [Column]
        public string Name { get; set; }

        [Column]
        public string Address { get; set; }

        [Column]
        public int Age { get; set; }
    }

    [Table("News")]
    public class News
    {
        [Key]
        [Column]
        public string Title { get; set; }

        [Column]
        public string Content { get; set; }

        [Column]
        [ForeignKey("User")]
        public string Author { get; set; }
    }

    public class MyContext : DbContext
    {
        private readonly string _connectionString;

        public MyContext()
        {
            this._connectionString = "DataSource=./mydb.db";
        }

        public MyContext(string connectionString)
        {
            this._connectionString = connectionString;
        }

        public DbSet<User> Users { get; set; }
        public DbSet<News> News { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite(_connectionString);
        }
    }
}

and my unit test code:和我的单元测试代码:

using System;
using System.Linq;
using dz1;
using Xunit;

namespace ApiTest
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {
            var ctx = new MyContext("DataSource=:memory:");

            ctx.Database.EnsureDeleted();
            ctx.Database.EnsureCreated();

            var u = new User();
            u.Name = "Mirko";
            u.Address = "Tamo 2";
            u.Age = 101;

            ctx.Users.Add(u);
            ctx.SaveChanges();

            Assert.True(ctx.Users.ToList().First().Name == "Mirko");
        }
    }
}

I read on the internets that EnsureCreated should be enough to create the tables in the in-memory database.我在互联网上读到 EnsureCreated 应该足以在内存数据库中创建表。 What am I missing?我错过了什么?

I get an error我收到一个错误

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---- Microsoft.Data.Sqlite.SqliteException: SQLite Error 1: 'no such table: User'.

How do I force the tables to get created?如何强制创建表?

I even tried using我什至尝试使用

            RelationalDatabaseCreator databaseCreator =
                (RelationalDatabaseCreator) ctx.Database.GetService<IDatabaseCreator>();

            var s = databaseCreator.GenerateCreateScript();

            ctx.Database.ExecuteSqlRaw(s);

but I don't get it.但我不明白。 Does the sql script even doesn't run? sql 脚本甚至没有运行吗?

Follow these steps, you should be able to get it working.按照这些步骤,你应该能够让它工作。

1) Create SQLite connection for in-memory database 1) 为内存数据库创建 SQLite 连接

2) Create the DbContextOptions for SQlite connection 2) 为 SQlite 连接创建 DbContextOptions

3) Pass the DbContextOptions to the DataContext. 3) 将 DbContextOptions 传递给 DataContext。 For this you need to have a overload in the DataContext accepting a DbContextOptions.为此,您需要在接受 DbContextOptions 的 DataContext 中有一个重载。

4) Call the dbContext.Database.EnsureCreated() to create the database. 4) 调用 dbContext.Database.EnsureCreated() 来创建数据库。

using(var connection = new SqliteConnection("DataSource=:memory:"))
{
    connection.Open();
    var options = new DbContextOptionsBuilder<DataContext>()
                   .UseSqlite(connection)                  
                   .Options;

    var dbContext = new DataContext(options);
    dbContext.Database.EnsureCreated();

    //You testing logic goes here.
}

5) Adding a overload constructor in DataContext 5)在DataContext中添加重载构造函数

public DataContext(DbContextOptions<DataContext> options) : base(options)
{

}

6) Database will be deleted with disposing the connection 6) 数据库将随着连接的处理而被删除

You can find a code sample in https://github.com/Wijithapaw/PMS/tree/sqlite/PMS.Api您可以在https://github.com/Wijithapaw/PMS/tree/sqlite/PMS.Api中找到代码示例

Cheers,干杯,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM