Entity Framework Core 1.1 In Memory Database falla al agregar nuevas entidades

entity-framework-core

Pregunta

Estoy usando el siguiente código en una prueba unitaria para la configuración de la prueba:

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();
}

Cuando se llega a SaveChangesAsync, EF lanza una excepción ArgumentException con el siguiente mensaje:

Ya se ha agregado un elemento con la misma clave. Clave: 1

También estoy usando un dispositivo para la clase de prueba unitaria que llena la base de datos con objetos del mismo tipo, aunque para esta prueba quiero esta configuración particular, así que quiero agregar estas nuevas entidades a la base de datos en la memoria. He intentado agregar las entidades en el DbSet (no el DbContext) y agregar las tres entidades por separado, en vano. Sin embargo, puedo agregar "simpleEntity" por separado (porque no se agrega en el dispositivo) pero EF se queja tan pronto como intento agregar "complexEntity" u "anotherEntity".

Parece que EF en la base de datos de memoria no puede manejar varias Adiciones en diferentes instancias del contexto. ¿Hay alguna solución para esto o estoy haciendo algo mal en mi configuración?

El databaseFixture en este caso es una instancia de esta clase:

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);
        }
    }
}

Respuesta popular

Puedes resolver este problema usando los accesorios de colección para que puedas compartir este dispositivo en varias clases de prueba. De esta manera, no creará su contexto varias veces y, por lo tanto, no obtendrá esta excepción:

Alguna información sobre la colección Fixture

Mi propio ejemplo:

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

}

Buena suerte, seb



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow