Основы Сущность 5 Код Первого Самосоединения

как бы я сопоставил следующие отношения в Entity Framework 5?

public class Item {
  public int Id { get; set; }
  public int? ParentItemId { get; set; }
  public string Value { get; set; }

  public Item ParentItem { get; set; }
  public List<Item> ChildItems { get; set; }
}

Я попытался это:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
  base.OnModelCreating(modelBuilder);

  modelBuilder.Entity<Item>()
              .HasOptional(i => i.ParentItem)
              .WithMany(i => i.ChildItems)
              .HasForeignKey(i => i.ParentItemId);
}

и так:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
  base.OnModelCreating(modelBuilder);

  modelBuilder.Entity<Item>()
              .HasMany(i => i.ChildItems)
              .WithOptional(i => i.ParentItem)
              .HasForeignKey(i => i.ParentItemId);
}

которые оба приводят к этой ошибке:

типы всех свойств в зависимой роли ссылочного ограничения должны совпадать с соответствующими типами свойств в главной роли.

если я начну с сопоставления базы данных, вот что сгенерированный объект выглядит так:

public partial class Item
{
    public Item()
    {
        this.ChildItems = new HashSet<Item>();
    }

    public int Id { get; set; }
    public Nullable<int> ParentItemId { get; set; }
    public string Value { get; set; }

    public virtual ICollection<Item> ChildItems { get; set; }
    public virtual Item ParentItem { get; set; }
}

Я знаю, что это будет работать, если я начну с db-first, мне просто нужно знать, как определить отношения в коде-first.

4 ответов


исключение означает следующее:

  • "типы всех свойств в зависимой роли " типы свойства FK, которое является ParentItemId и имеет тип int? модели
  • "соответствующие типы свойств в главной роли " являются типами свойства PK, которое является Id и имеет тип int модели

они одинаковы (недействительность не имеет значения). Однако исключение говорит, что нет.

исключение обычно возникает только если типы не совпадают, например, если у вас long (или любой другой тип) для ПК и int? для FK.


в коде сначала измените класс сущности следующим образом:

   public class Item 
   {
      public Item()
      {
            this.ChildItems = new HashSet<Item>();
      }

      public int Id { get; set; }
      public Nullable<int> ParentItemId { get; set; }
      public string Value { get; set; }

      public virtual Item ParentItem { get; set; }
      public virtual ICollection<Item> ChildItems { get; set; }
  }

напишите в контекстный файл следующий код:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Item>()
                    .HasOptional(i => i.ParentItem)
                    .WithMany(i => i.ChildItems)
                    .HasForeignKey(i => i.ParentItemId);
    }

думаю, это должно сработать.


почему бы не попробовать это:

 public class Item 
   {
      public Item()
      {
            ChildItems = new HashSet<Item>();
      }

      public int Id { get; set; }
      public int? ParentItemId { get; set; }
      public string Value { get; set; }

      public virtual Item ParentItem { get; set; }
      public virtual ICollection<Item> ChildItems { get; set; }
  }

и в вашем классе DataContex:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Item>()
                    .HasOptional(i => i.ParentItem)
                    .WithMany()
                    .HasForeignKey(i => i.ParentItemId);
    }

надеюсь, это сработает.

также здесь есть хорошая статья: как настроить само ссылающуюся сущность в коде First http://blogs.microsoft.co.il/gilf/2011/06/03/how-to-configure-a-self-referencing-entity-in-code-first/


попробуйте использовать способ mapKey, а не использовать HasForeignKey. Как

modelBuilder.Entity<Course>()
    .HasRequired(c => c.Department)
    .WithMany(t => t.Courses)
    .Map(m => m.MapKey("ChangedDepartmentID"));