Код Entity Framework: первая настройка «многие ко многим» для существующих таблиц

У меня есть следующие таблицы Essence, EssenseSet и Essense2EssenceSet

Essense2EssenceSet — это таблица связывания, которая создает отношение M:M.

Хотя сначала мне не удалось заставить отношения M:M работать в коде EF.

Вот мой код:

[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, поскольку один объект не может быть идентифицирован как источник исключения.

Я не могу найти проблему. Буду очень признателен за помощь в правильной настройке. Спасибо!


person user169867    schedule 17.05.2011    source источник


Ответы (1)


Удалите свой класс модели Essence2EssenceSet. Если соединительная таблица содержит только ключи связанных сущностей, участвующих в отношениях «многие ко многим», ее не нужно отображать как сущность. Также убедитесь, что ваше свободное сопоставление отношений «многие ко многим» указывает схему для таблицы:

mb.Entity<Essence>()
  .HasMany(e => e.EssenceSets)
  .WithMany(set => set.Essences)
  .Map(mc =>
      {
          mc.ToTable("Essence2EssenceSet", "Com");
          mc.MapLeftKey("EssenceID");
          mc.MapRightKey("EssenceSetID");
      });
person Ladislav Mrnka    schedule 17.05.2011
comment
Вы правы, спасибо! Я забыл о схеме таблицы. Считаете ли вы дурным тоном раскрывать соединительную таблицу в подобных случаях, когда она не (загружена) дополнительными полями? - person user169867; 17.05.2011
comment
@Ladislav Mrnka, нет ли способа сделать это с явным определением таблицы и использованием DataAnnotations? Мне намного проще поддерживать и комментировать мой код, используя DataAnnotations вместо Fluent Mapping. - person Scott; 24.08.2011
comment
@Scott: я не знаю, как это сделать с помощью аннотаций данных. Аннотации данных предназначены для самых простых сценариев, когда вы позволяете EF создавать базу данных и не беспокоитесь о ее структуре или именовании. - person Ladislav Mrnka; 24.08.2011
comment
Что делать, если в существующей таблице есть дополнительные поля. Как я могу сопоставить их? - person Leon; 03.03.2012
comment
@Leon: В таком случае вы должны отобразить его как отдельный объект. - person Ladislav Mrnka; 04.03.2012
comment
@Ladislav Mrnka: Вы имеете в виду вместо многих ко многим рассматривать это как 2 один ко многим? Если нет, не могли бы вы показать мне, как это (многие ко многим) можно сделать, предполагая, что Essence2EssenceSet имеет дополнительное поле? Спасибо - person Leon; 04.03.2012
comment
@Leon: Да, вы создадите новый объект для своей соединительной таблицы и замените отношение «многие ко многим» двумя отношениями «один-два-многие». - person Ladislav Mrnka; 05.03.2012
comment
@Nikos Я знаю, что это очень поздно, но правильное место находится в OnModelCreating (override) вашего подкласса DbContext (вероятно, называемого BaseContext). - person bug; 16.05.2019