【问题标题】:EF Core: The instance of entity type cannot be tracked because another instance with the same key valueEF Core:无法跟踪实体类型的实例,因为另一个实例具有相同的键值
【发布时间】:2020-09-19 21:58:34
【问题描述】:

假设我们有以下两个数据库表:

Foo:
> FooId (PK)
> FooName

Bar:
> BarId (PK, FK)
> Comment
> Other columns...

我有以下 EF 映射:

[Table("Foo")]
public class Foo
{
    [Key]
    public long FooId { get; set; }

    public string FooName { get; set; }

    // (0-n) relation
    // public List<Bar> Bars { get; set; }
}

[Table("Bar")]
public class Bar
{
    // PK/FK
    [Key, ForeignKey("Foo")]
    public long BarId { get; set; }

    public string Comment { get; set; }
}

实体“Bar”只有一个外键作为主键。 每当我尝试像这样插入新的 Bar 实体时:

var demoList = new List<Bar>();
// Populate demoList with random data
_context.Bars.AddRange(demoList);
_context.SaveChanges();

我遇到了这个异常:

'The instance of entity type 'Bar' cannot be tracked because another instance with the same key value for {'BarId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.'

EF 正在考虑“BarId”必须是唯一的,因为该属性被标记为“Key”,但它是一对多关系中的 PK/FK(“Foo”可以有 0 个或多个“Bar”),什么请问我这里不见了?

【问题讨论】:

标签: c# .net entity-framework asp.net-core entity-framework-core


【解决方案1】:

如果Foo 可以有零个或多个Bars,则它是一对多关系。如果关系是一对零或一,您通常会创建一个作为 PrimaryKeyForiegnKey 的密钥。因此,根据您的要求,您的模型应该更像如下:

[Table("Foo")]
public class Foo
{
    [Key]
    public long FooId { get; set; }

    public string FooName { get; set; }

    public virtual List<Bar> Bars { get; set; }
}

[Table("Bar")]
public class Bar
{

    [Key]
    public long BarId { get; set; }

    public long FooId { get; set; }

    [ForeignKey("FooId")]
    public virtual Foo Foo { get; set; }

    public string Comment { get; set; }
}

【讨论】:

  • “BarId”在“Bar”表中不相关,“FooId”已经是同一张表中的PK/FK。获取链接到“FooId”的“Bar”列表的典型 SQL 查询如下:SELECT * FROM Bar WHERE FooId = 1。“BarId”不会在任何地方使用。
  • @Karim 为什么要将 FooId 用作 PK 和 FK?只有当 Foo 可以有 0 或 1 个 Bar 时,您才会这样做。但是您的要求是 Foo 可能有 0 个或多个 Bars
  • 是的,你是对的,如果我想建立一个零对多的关系,我确实需要一个 BarId
猜你喜欢
  • 2018-06-20
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多