Entity Framework Code First 多对多关系的现有表设置

13

我有以下的表格:EssenceEssenseSetEssense2EssenceSet

Essense2EssenceSet 是用来创建 M:M 关系的链接表。

然而,我一直无法在 EF Code First 中使 M:M 关系起作用。

这是我的代码:

[Table("Essence", Schema = "Com")]
    public class Essence
    {
        public int EssenceID { get; set; }
        public string Name { get; set; }
        public int EssenceTypeID { get; set; }
        public string DescLong { get; set; }
        public string DescShort { get; set; }
        public virtual ICollection<EssenceSet> EssenceSets { get; set; }
        public virtual EssenceType EssenceType { get; set; }
    }

    [Table("EssenceSet", Schema = "Com")]
    public class EssenceSet
    {
        public int EssenceSetID { get; set; }
        public int EssenceMakerID { get; set; }
        public string Name { get; set; }
        public string DescLong { get; set; }
        public string DescShort { get; set; }

        public virtual ICollection<Essence> Essences { get; set; }
    }

[Table("Essence2EssenceSet", Schema = "Com")]
    public class Essence2EssenceSet
    {
        //(PK / FK)
        [Key] [Column(Order = 0)] [ForeignKey("Essence")] public int EssenceID { get; set; }
        [Key] [Column(Order = 1)] [ForeignKey("EssenceSet")] public int EssenceSetID { get; set; }

        //Navigation
        public virtual Essence Essence { get; set; }
        public virtual EssenceSet EssenceSet { get; set; }
    }
            public class EssenceContext : DbContext
            {
                public DbSet<Essence> Essences { get; set; }
                public DbSet<EssenceSet> EssenceSets { get; set; }
                public DbSet<Essence2EssenceSet> Essence2EssenceSets { get; set; }

                protected override void OnModelCreating(DbModelBuilder mb)
                {
                    mb.Entity<Essence>()
                        .HasMany(e => e.EssenceSets)
                        .WithMany(set => set.Essences)
                        .Map(mc =>
                            {
                                mc.ToTable("Essence2EssenceSet");
                                mc.MapLeftKey("EssenceID");
                                mc.MapRightKey("EssenceSetID");
                            });
                }
        }

这是我正在尝试运行的代码:

    Essence e = new Essence();
                            e.EssenceTypeID = (int)(double)dr[1];
                            e.Name          = dr[2].ToString();
                            e.DescLong      = dr[3].ToString();

                            //Get Essence Set
                            int setID = (int)(double)dr[0];
                            var set = ctx.EssenceSets.Find(setID);
                            e.EssenceSets = new HashSet<EssenceSet>();
                            e.EssenceSets.Add(set);
                            ctx.Essences.Add(e);
ctx.SaveChanges();

以下是错误信息:

在保存不公开其关系外键属性的实体时发生错误。由于无法将单个实体标识为异常源,因此EntityEntries属性将返回null。

我无法找到问题所在,非常感谢帮助正确设置。 谢谢!

1个回答

26

删除你的Essence2EssenceSet模型类。如果连接表只包含参与多对多关系的相关实体的键,则无需将其映射为实体。还要确保你的流畅多对多关系映射指定了表的架构:

mb.Entity<Essence>()
  .HasMany(e => e.EssenceSets)
  .WithMany(set => set.Essences)
  .Map(mc =>
      {
          mc.ToTable("Essence2EssenceSet", "Com");
          mc.MapLeftKey("EssenceID");
          mc.MapRightKey("EssenceSetID");
      });

你是正确的,谢谢!我确实忘记了表模式。您觉得在这种情况下暴露联接表是否不好?即使它没有用于(加载)其他字段? - user169867
@Ladislav Mrnka,难道没有一种方法可以通过明确定义表并使用DataAnnotations来完成这个任务吗?我发现使用DataAnnotations而不是Fluent Mapping更容易维护和注释我的代码。 - Scott
1
如果现有表中有额外的字段,我该如何映射它们? - Leon
@Leon:在这种情况下,你必须将其映射为一个独立的实体。 - Ladislav Mrnka
@Leon:是的,您将为连接表创建一个新实体,并使用两个一对多关系替换多对多关系。 - Ladislav Mrnka
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接