Entity framework core 英孚核心赢得';t让我添加多个相同类型的新实体

Entity framework core 英孚核心赢得';t让我添加多个相同类型的新实体,entity-framework-core,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.No

我有以下实体和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)
    {
    }
}
公共类Foo
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int FooId{get;set;}
公共条{get;set;}
}
公共类酒吧
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.None)]
公共int BarId{get;set;}
公共字符串Baz{get;set;}
}
公共类上下文:DbContext
{
公共DbSet Foos{get;set;}
公共DbSet条{get;set;}
公共上下文(DbContextOptions):基本(选项)
{
}
}
以及以下测试代码:

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);
}
使用(var context=new ReproContext(new DbContextOptionsBuilder())
.UseInMemoryDatabase(Guid.NewGuid().ToString(“D”))
.EnableSensitiveDataLogging()
(可选方案)
{
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(因此对其初始化的控制不那么精确),我该怎么办呢?

它不起作用,因为当您使用新的工具栏添加新的foo时。新的条指定了0,因为这是默认的int。所以当您将它们添加到上下文中时,您有两个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);
    }

在barId上。

它不起作用,因为当你用新条添加新foo时。新的条指定了0,因为这是默认的int。所以当您将它们添加到上下文中时,您有两个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);
    }

在barId上。

数据库生成选项。无
表示您需要自己指定密钥,您的意思是这样做吗?@DavidG:当然,谢谢。不知道为什么我在排除故障时没有注意到…:/当然,有了这个更改,它就可以工作了。
DatabaseGeneratedOption.None
意味着您需要自己指定密钥,您的意思是这样吗?@DavidG:当然,谢谢。不知道为什么我在排除故障时没有注意到…:/有了这个改变,当然可以了。当然,谢谢。不知道为什么我在排除故障时没有注意到…:/有了这个改变,当然可以了。当然,谢谢。不知道为什么我在排除故障时没有注意到…:/当然,有了这一改变,它就起作用了。