实体框架允许多对多关系中的重复

时间:2015-09-17 19:09:14

标签: c# sql entity-framework

我有两个对象 - 父母和孩子的关系多对多,问题是1个父母可以有2个相同的孩子,但EF只保存这个关系一次。

我发现只有2个有效的解决方案:

  1. count列添加到表格中并手动填写
  2. 不使用多对多,但将其拆分为一对多和多对一 但我不喜欢这个解决方案,因为我希望可以有更简单的解决方案。
  3. 你能帮我吗?

    编辑: 联结表的示例:

    1-1

    1-1

    1-2

    1-3

    2-3

    代码: 模型

    public class Item
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int id { get; set; }
    
        public virtual ICollection<Item> childs { get; set; }
        public virtual ICollection<Item> parents { get; set; }
    }
    

    数据库上下文

    modelBuilder.Entity<Item>().
    HasMany(i => i.childs).
    WithMany(i2 => i2.parents).
    Map(
    m =>
    {
    m.MapLeftKey("parentId");
    m.MapRightKey("childId");
    m.ToTable("itemRelationship");
    });
    

3 个答案:

答案 0 :(得分:1)

关系数据库与有关。集合是已识别实体的不同集合。然而,您的联结表,就像你想象的那样,是一个。这违反了关系理论的基本原理。像往常一样,一次违规就会引发其他违规行为。没有唯一的主键,身份,是下一个。如果你想要的话,不能通过外键引用这些联结记录是另一个。

所以不要这样做。

我认为这里的错误是你要表达的事实&#34; An&#34}的B个实例。按您创建的行数。但是这个数字是该关联的一个属性。

让我们看一个例子:文章和文字。

您可以通过纯粹的多对多关联来表达ArticleWord之间的关系。此关联表示: Article包含这些 Word。观看指示代词(这些,这些)。他们意味着身份。每篇文章都有一个实例,数据库中每个单词都有一个实例。

如果要存储单词出现的次数,则必须将此数字作为属性添加到关联中。一个事实永远不会被许多行建模。单行描述了事实&#34;此Article出现了n&#34; Word。在实体框架中,这意味着关联成为类模型中的类,例如ArticleWord。关联的多重性为Article 1-n ArticleWord n-1 Word

答案 1 :(得分:0)

一种解决方案是首先定义关系表。该表的主键是它包含的2个外键的组合,它将允许该组合键看起来像:

1-1,

2-1,

2-2

但不是:

1-1

1-1

1-2

2-1

答案 2 :(得分:0)

我同意Gert关于关系数据的核心概念是集合的观点。为此,我建议您找到使它们独特的另一件事。就像添加时间戳或按日期创建一样。如果您真的需要在那儿买到副本。但这又回到关系数据被标准化为集合的状态。这是有关DB Normalization

的链接
[Key, Column(Order =2), DatabaseGenerated(DatabaseGeneratedOption.None)]
public DateTime DateCreated { get; set; }

[Timestamp]
public byte[] RowVersion { get; set; }

时间戳主要用于并发,但是您可以将它们添加到密钥中。

我也很好奇您需要在多对多表中重复哪些方案。只有两列的两条记录完全相同,这意味着该关系被表达两次,因此不会创建其他关系。

这就像说我的姐姐是我的姐姐,有人说她又是我的姐姐,并没有改变她是我的姐姐的事实,它没有给我两个她,她仍然在收藏中,她由于数据库规范化,不能两次出现在集合中。我可以在集合中对她进行两次计数,但这并不能改变只有一个(在另一张桌子中)她的事实。如果需要她两个,则应该有另一个ID不同的记录。