エンティティフレームワークのCore 1.1 In Memoryデータベースが新しいエンティティの追加に失敗する

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

私は同じ種類のオブジェクトをデータベースに取り込むユニットテストクラス用のフィクスチャも使用していますが、このテストではこの特定の設定をしたいので、これらの新しいエンティティをメモリデータベースに追加します。私はDbSet(DbContextではない)のエンティティを追加しようとしましたが、3つのエンティティを個別に無駄に追加しようとしました。しかし、私は "simpleEntity"を別途追加することができますが(これはフィクスチャに追加されていないためです)、 "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);
        }
    }
}

人気のある回答

コレクションフィクスチャを使用することでこの問題を解決できるため、このフィクスチャを複数のテストクラスに分けて共有できます。このようにしてコンテキストを何度も構築しないので、この例外は発生しません。

コレクションのフィクスチャに関するいくつかの情報

自分の例:

[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[]>
        {
            (...)
        };
}

}

幸運、セブ



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ