【问题标题】:How do you detach an object within a parent object in EF Core?如何在 EF Core 的父对象中分离对象?
【发布时间】:2020-07-23 13:07:55
【问题描述】:

我有一个单元测试来测试在数据库中插入相同的对象两次将给出ArgumentException。我有这门课:

public class Foo
{
    public Guid Id { get; set; }
    public List<Bar> Bars { get; set; }
}

还有这个单元测试:

    [Fact]
    public async Task AddFooAsync_ContainsExistingFoo_TrowsArgumentException()
    {
        // arrange
        using var context = new MyDbContext(MockDbContext.CreateInMemoryContext());
        var fooRepository = new FooRepository(context, cacheService, myMapper); // cacheService and myMapper are succesfully instantiated elsewhere.
        
        // Add a Foo to the database.
        var myFoo = new Foo
        {
            Id = Guid.Parse("abc-123"),
            Bars = new List<Bar> { new Bar { Id = Guid.Parse("def-456") }  }
        };
        _context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        _context.Foo.Add(myFoo);
        _context.SaveChanges();

        _context.Entry(myFoo).State = EntityState.Detached;
        _context.SaveChanges();

        // This is a DTO object that is almost the same as the Foo entity above. Same for the Bar List
        var fooDTO = new FooDTO 
        {
            Id = Guid.Parse("abc-123"),
            Bars = new List<BarDTO> { new BarDTO { Id = Guid.Parse("def-456") }  }
        }

        // act + assert 
        await Assert.ThrowsAsync<ArgumentException>(() => fooRepository.AddFooAsync(fooDTO));
    }

AddFooAsync 方法如下所示:

    public async Task<FooDTO> AddFooAsync(FooDTO foo)
    {
        // use AutoMapper to turn the Foo DTO into a Foo entity. 
        var dbFoo = _mapper.Map<Foo>(foo);

        _dbContext.Foos.Add(dbFoo);
        await _dbContext.SaveChangesAsync();

        return _mapper.Map<UserDTO>(dbUser);
    }

此方法在_dbContext.Foos.Add(dbFoo); 行上崩溃,并抛出InvalidOperationException 而不是我预期的ArgumentException。我收到以下文字:

无法跟踪实体类型“Bar”的实例,因为另一个 键值为“{Id: def-456 }”的实例已经存在 跟踪。附加现有实体时,确保只有一个实体 附加了具有给定键值的实例

我最好的猜测是 EF 也在跟踪 Bar 对象,这在执行双插入时给我带来了问题。解决此问题的最佳方法是什么?

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    如果适合你,你可以分离所有东西:

        foreach (var e in _dbContext.ChangeTracker.Entries())
        {
            e.State = EntityState.Detached;
        }
    

    【讨论】:

    • 就是这样,我没有意识到我可以通过这种方式访问​​我的 Bar 类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多