entity-framework-core - Entity Framework Core 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 并显示以下消息:

An item with the same key has already been added. Key: 1

我还为单元测试类使用了一个固定装置,该类用相同类型的对象填充数据库,但对于此测试,我想要这个特定的设置,因此我想将这些新实体添加到内存数据库中。我尝试在 DbSet (不是 DbContext)上添加实体并分别添加所有三个实体,但无济于事。不过,我可以单独添加“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);
        }
    }
}

最佳答案

您可以通过使用 Collection Fixtures 来解决这个问题,这样您就可以在多个测试类之间共享这个fixture。这样您就不会多次构建上下文,因此不会出现此异常:

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

}

祝你好运, 塞布

关于entity-framework-core - Entity Framework Core 1.1 内存数据库无法添加新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40973381/

相关文章:

c# - OwnsOne 从表键中删除 IDENTITY

c# - 如果字段包含 null,则整个连接结果为 null

asp.net-core - EF Core 5 TPT 和身份 (CRUD)

c# - 当表存在时,代码优先 EntityFrameworkCore.Sqlite 3.1.1 上为 "No such table"

.net-core - 是否有任何理由使用 SaveChangesInterceptor 而不是覆盖 OnBeforeSaveChanges 和 OnAfterSaveChanges?

c# - 首先在 Entity Framework 代码中定义外键

c# - ThenInclude 在 EF Core 查询中无法识别

c# - EF 核心 'another instance is already being tracked'

c# - 如何在代码优先中设置身份种子值?

c# - 如何使用 Fluent API 正确控制 EF Core 中的级联删除?