Entity Framework 4.1 — Сначала код: отношения «многие ко многим»

#c# #.net #sql #entity-framework #entity-framework-4.1

#c# #.net #sql #entity-framework #entity-framework-4.1

Вопрос:

Я хочу построить отношение, подобное этому (зона находится по соседству с x другими зонами)

 public class Zone
{
    public string Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ZoneNeighourhood> ZoneNeighourhoods { get; set; }
}

public class ZoneNeighbourhood
{
    public virtual Zone Zone1 { get; set; }
    public virtual Zone Zone2 { get; set; }
}
  

К сожалению, это не сработает, потому что FK, сгенерированные EF, неверны… Как я могу заставить подобную структуру работать?

Пример с 3 зонами: зона 1, зона 2, зона 3

Зона 1 соседствует:

Зона 2, зона 3

Соседи зоны 2:

Зона 1

Соседи зоны 3:

Zone1

Есть какие-нибудь советы?

Комментарии:

1. @Dave: Извините, взаимосвязь между Zone и ZoneNeighbourhood для меня неясна. Я думаю, вы имеете в виду, что зона может находиться в другой зоне, которая сама по себе может быть дочерней по отношению к другой «Суперзоне»… Это правильно?

2. Нет, я имею в виду это, как в примере, который я добавил… Это похоже на неявное соседнее отношение.. как и в случае с людьми: мистер Смит является соседом мистера Джонса, и поэтому мистер Джонс неявно является соседом мистера Смита

Ответ №1:

Ваше отображение неверно. Вы создаете объект, ссылающийся на себя, поэтому вам нужна отдельная коллекция для входящих и исходящих отношений. Одной коллекции недостаточно.

 public class Zone 
{
    public string Id { get; set; }
    public string Name { get; set; }
    [InverseProperty("NeighbourOf")]
    public virtual ICollection<Zone> NeighbourTo { get; set; }
    [InverseProperty("NeighbourTo")]
    public virtual ICollection<Zone> NeighbourOf { get; set; }
}
  

Вам не нужно отображать таблицу соединений, если вы также не хотите добавить некоторые дополнительные свойства к связи.

Если вам нужна только одна коллекция, вы должны использовать fluent mapping:

 public class Zone 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Zone> Neighours { get; set; }
}

public class Context : DbContext
{
    public DbSet<Zone> Zones { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Zone>()
                    .HasMany(z => z.Neighbours)
                    .WithMany();
    }
}
  

Комментарии:

1. Хороший ответ, спасибо. Но я получаю сообщение «Атрибут InversePropertyAttribute для свойства ‘NeighourTo’ для типа ‘Zone’ недопустим», когда я использую класс, подобный предложенному вами в первом случае

2. @David: Это было из-за типа в именах свойств. Я отредактировал его. Теперь это должно сработать.

Ответ №2:

Дэйв,

Как насчет того, чтобы просто:

 public class Zone {
    public string Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Zone> Neighours { get; set; }
}
  

Или я что-то упускаю? Вам НУЖНО моделировать окрестности как внешнюю сущность по какой-либо другой причине? Интересно, какую схему базы данных сгенерирует для этого Entity-Framework… Я НЕ эксперт, на самом деле я новичок в этой области. Я не ДУМАЮ, что у этого есть проблема с самореферентными таблицами, подобными этой… по крайней мере, ничто из того, что я читал до сих пор, не указывает на это. Давайте попробуем и выясним 😉

Приветствия. Кит.