实体框架核心唯一索引测试 [英] Entity Framework Core Unique Index testing
问题描述
我有一个模型课:
public class Work
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
}
我想要这个 Work.Name
将是唯一的,因此我定义了 DbContext
:
I want this Work.Name
will be unique, so I define the DbContext
:
public class MyDbContext : DbContext
{
public MyDbContext () : base() { }
public MyDbContext (DbContextOptions<MyDbContext > options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Work>(entity =>
entity.HasIndex(e => e.Name).IsUnique()
);
}
public DbSet<Work> Works { get; set; }
}
我想对此进行测试,因此我进行了如下测试:
And I want to test this, so I have a test like this:
[Fact]
public void Post_InsertDuplicateWork_ShouldThrowException()
{
var work = new Work
{
Name = "Test Work"
};
using (var context = new MyDbContext (options))
{
context.Works.Add(work);
context.SaveChanges();
}
using (var context = new MyDbContext (options))
{
context.Works.Add(work);
context.SaveChanges();
}
using (var context = new MyDbContext (options))
{
Assert.Equal(1, context.Works.Count());
}
}
(选项
对象包含 InMemoryDatabase
)的设置
我真的不知道要检查什么,但是测试在 Assert
中失败,而不是在第二个 SaveChanges()
中失败。数据库(上下文
)包含两个对象,它们具有相同的 Name
。
I don't really know what to check, but the test failed in the Assert
, not in the second SaveChanges()
. The database (the context
) contains two objects with the same Name
.
我遍历了所有相关问题,但是我没有看到任何人回答我的询问。
I went over all the relevant questions, but I did not see anyone answering what I was asking.
推荐答案
正如其他人指出的那样,InMemory数据库提供程序会忽略所有可能的约束。
我的建议是使用具有内存中功能的Sqlite提供程序,这将为重复的唯一键引发异常。
As others pointed out InMemory database provider ignore all possible constraints.
My suggestion would be then to use Sqlite provider with "in-memory' feature, which will throw an exception for duplicate unique keys.
public MyDbContext CreateSqliteContext()
{
var connectionString =
new SqliteConnectionStringBuilder { DataSource = ":memory:" }.ToString();
var connection = new SqliteConnection(connectionString);
var options = new DbContextOptionsBuilder<MyDbContext>().UseSqlite(connection);
return new MyDbContext(options);
}
private void Insert(Work work)
{
using (var context = CreateSqliteContext())
{
context.Works.Add(work);
context.SaveChanges();
}
}
[Fact]
public void Post_InsertDuplicateWork_ShouldThrowException()
{
var work1 = new Work { Name = "Test Work" };
var work2 = new Work { Name = "Test Work" };
Insert(work1);
Action saveDuplicate = () => Insert(work2);
saveDuplicate.Should().Throw<DbUpdateException>(); // Pass Ok
}
这篇关于实体框架核心唯一索引测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!