實體框架核心1.1在內存數據庫中無法添加新實體

entity-framework-core

我在測試設置的單元測試中使用以下代碼:

var simpleEntity = new SimpleEntity();
var complexEntity = new ComplexEntity
{
    JoinEntity1List = new List<JoinEntity1>
    {
        new JoinEntity1
        {
            JoinEntity2List = new List<JoinEntity2>
            {
                new JoinEntity2
                {
                    SimpleEntity = simpleEntity
                }
            }
        }
    }
};
var anotherEntity = new AnotherEntity
{
    ComplexEntity = complexEntity1
};

using (var context = databaseFixture.GetContext())
{
    context.Add(anotherEntity);
    await context.SaveChangesAsync();
}

達到SaveChangesAsync時,EF會拋出ArgumentException並顯示以下消息:

已添加具有相同鍵的項目。關鍵:1

我正在使用一個fixture也用於單元測試類,它使用相同類型的對象填充數據庫,但是對於這個測試,我想要這個特定的設置,所以我想將這些新實體添加到內存數據庫中。我已經嘗試在DbSet(不是DbContext)上添加實體,並且分別添加所有三個實體都無濟於事。然而,我可以單獨添加“simpleEntity”(因為它沒有添加到fixture中)但是當我嘗試添加“complexEntity”或“anotherEntity”時,EF會抱怨。

看起來內存數據庫中的EF無法在上下文的不同實例上處理多個Add。有沒有解決方法或我在設置中做錯了什麼?

在這種情況下,databaseFixture是此類的一個實例:

namespace Test.Shared.Fixture
{
    using Data.Access;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.DependencyInjection;

    public class InMemoryDatabaseFixture : IDatabaseFixture
    {
        private readonly DbContextOptions<MyContext> contextOptions;

        public InMemoryDatabaseFixture()
        {
            var serviceProvider = new ServiceCollection()
            .AddEntityFrameworkInMemoryDatabase()
            .BuildServiceProvider();

            var builder = new DbContextOptionsBuilder<MyContext>();
            builder.UseInMemoryDatabase()
                   .UseInternalServiceProvider(serviceProvider);

            contextOptions = builder.Options;
        }

        public MyContext GetContext()
        {
            return new MyContext(contextOptions);
        }
    }
}

熱門答案

您可以使用Collection Fixtures解決此問題,以便跨多個測試類共享此fixture。這樣您就不會多次構建上下文,因此您不會遇到此異常:

有關收集夾具的一些信息

我自己的例子:

[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{  }

[Collection("Database collection")]
public class GetCitiesCmdHandlerTests : IClassFixture<MapperFixture>
{
    private readonly TecCoreDbContext _context;
    private readonly IMapper _mapper;

    public GetCitiesCmdHandlerTests(DatabaseFixture dbFixture, MapperFixture mapFixture)
    {
        _context = dbFixture.Context;
        _mapper = mapFixture.Mapper;
    }

    [Theory]
    [MemberData(nameof(HandleTestData))]
    public async void Handle_ShouldReturnCountries_AccordingToRequest(
        GetCitiesCommand command,
        int expectedCount)
    {
        (...)
    }

    public static readonly IEnumerable<object[]> HandleTestData
        = new List<object[]>
        {
            (...)
        };
}

}

祝你好運,Seb



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow