[英]C# In memory databases share indexes?
所以我正在測試我的代碼中添加和刪除數據庫中的數據的部分內容。 我正在為每個單元測試設置一個內存數據庫,以確保每個測試都有一個完全“干凈的”。 但是,我遇到了一個非常奇怪的問題。 我在下面省略了一些代碼,但它顯示了我的一般方法:
[TestFixture]
internal class EventControllerTest
{
[Test]
public void CreateEventController()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "CreateEventController1")
.Options;
var context = new ApplicationDbContext(options, null);
//Add eventType.
realEventService = new EventService(context, currentUserService.Object);
realEventService.CreateEventType(new EventTypeData
{
Color = "Pink"
});
//ASSERTS
}
[Test]
public void GetEventController()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "GetEventController1")
.Options;
var context = new ApplicationDbContext(options, null);
//Add eventType.
realEventService = new EventService(context, currentUserService.Object);
realEventService.CreateEventType(new EventTypeData
{
Color = "Pink",
});
//ASSERTS
}
}
現在,如果我自己運行這些測試中的每一個,它們會在我最初檢查EventType的Id時通過,它們都是1.但是,如果我按順序運行所有測試,則第二次測試失敗。 它失敗了,因為它添加的EventType實際上具有2而不是1的id! 但是,數據庫僅包含一個EventType條目。 我在數據庫上有不同的名稱,據我所知,這意味着它們完全不同。 然而,自動遞增的索引由於某種原因剛剛增加並用於我的第二次測試。 所以澄清一下:
如何完全分離這些數據庫?
看起來像一個開放的問題/錯誤: https : //github.com/aspnet/EntityFrameworkCore/issues/6872
他們提供了一個擴展方法作為修復(代碼從那里解除):
public static class DbContextExtensions
{
public static void ResetValueGenerators(this DbContext context)
{
var cache = context.GetService<IValueGeneratorCache>();
foreach (var keyProperty in context.Model.GetEntityTypes()
.Select(e => e.FindPrimaryKey().Properties[0])
.Where(p => p.ClrType == typeof(int)
&& p.ValueGenerated == ValueGenerated.OnAdd))
{
var generator = (ResettableValueGenerator)cache.GetOrAdd(
keyProperty,
keyProperty.DeclaringEntityType,
(p, e) => new ResettableValueGenerator());
generator.Reset();
}
}
}
public class ResettableValueGenerator : ValueGenerator<int>
{
private int _current;
public override bool GeneratesTemporaryValues => false;
public override int Next(EntityEntry entry)
=> Interlocked.Increment(ref _current);
public void Reset() => _current = 0;
}
要使用,請調用context.ResetValueGenerators(); 在第一次使用上下文之前以及調用EnsureDeleted的任何時間。 例如:
using (var context = new BlogContext())
{
context.ResetValueGenerators();
context.Database.EnsureDeleted();
context.Posts.Add(new Post {Title = "Open source FTW", Blog = new Blog {Title = "One Unicorn"}});
context.SaveChanges();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.