EF Core不会让我添加多个相同类型的新实体

时间:2017-12-15 14:42:38

标签: entity-framework-core

我有以下实体和DbContext:

public class Foo
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FooId { get; set; }

    public Bar Bar { get; set; }
}

public class Bar
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BarId { get; set; }

    public string Baz { get; set; }
}

public class ReproContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }

    public DbSet<Bar> Bars { get; set; }

    public ReproContext(DbContextOptions<ReproContext> options) : base(options)
    {
    }
}

以及以下测试代码:

using (var context = new ReproContext(new DbContextOptionsBuilder<ReproContext>()
    .UseInMemoryDatabase(Guid.NewGuid().ToString("D"))
    .EnableSensitiveDataLogging()
    .Options))
{
    var foos = new[]
    {
        new Foo {Bar = new Bar {Baz = "1"}},
        new Foo {Bar = new Bar {Baz = "2"}}
    };

    context.Foos.AddRange(foos);
}

这会引发InvalidOperationException

  

无法跟踪实体类型“Bar”的实例,因为已经跟踪了另一个键值为“BarId:0”的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

我从错误消息中了解到这不起作用,但我该如何解决呢?当我不是手动构建实体而是使用AutoFixture(因此对其初始化的控制较少)时,我该怎么办?

1 个答案:

答案 0 :(得分:3)

它不起作用,因为当你用新栏添加新的foo时。新栏已分配0,因为这是默认的int。因此,当您将它们添加到上下文时,您有2个id = 0的实体。 BarId是关键列,因此不允许这样做。 指定不同的ID:

    using (var context = new ReproContext(new DbContextOptionsBuilder<ReproContext>()
        .UseInMemoryDatabase(Guid.NewGuid().ToString("D"))
        .EnableSensitiveDataLogging()
        .Options))
    {
        var foos = new[]
        {
            new Foo {Bar = new Bar {Baz = "1", BarId = 1}},
            new Foo {Bar = new Bar {Baz = "2", BarId = 2}}
        };

        context.Foos.AddRange(foos);
    }

或使用:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

on barId。