簡體   English   中英

C#在內存數據庫中共享索引?

[英]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條目。 我在數據庫上有不同的名稱,據我所知,這意味着它們完全不同。 然而,自動遞增的索引由於某種原因剛剛增加並用於我的第二次測試。 所以澄清一下:

  • 如果我運行CreateEventController(),其EventType條目的id為1。
  • 如果我運行GetEventController(),它的EventType條目獲取id
    一。
  • 如果我運行CreateEventController()然后運行GetEventController(),
    CreateEventController()中的EventType條目為1,GetEventController()中的EventType條目ID為2!

如何完全分離這些數據庫?

看起來像一個開放的問題/錯誤: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM