EF 4.1 Проблема с отображением - PullRequest
7 голосов
/ 22 мая 2011

У меня есть класс, имеющий отношение к себе:

public class Person
{
    public long ID { get; set; }
    public string Name { get; set; }

    public virtual Person Mother { get; set; }
    public virtual Person Father { get; set; } 
}

Когда EF 4.1 пытается отобразить этот класс, я получаю следующую ошибку: «Невозможно определить основной конец ассоциациимежду типами «Model.Person» и «Model.person».Основной конец этой ассоциации должен быть явно сконфигурирован с использованием либо API-интерфейса беглых отношений, либо аннотаций данных. '

Я уже пробовал решение темы EF 4.1 - Отношения модели , но безуспешно.

Как я могу это исправить?

Спасибо!

Ответы [ 3 ]

9 голосов
/ 22 мая 2011

Поскольку это, естественно, отношения «один ко многим» (человек должен иметь одного отца и одну мать, но может иметь много сыновей и дочерей), я бы смоделировал это так:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Mother)
        .WithMany();
}

Это будетсоздайте два обязательных внешних ключа в таблице базы данных с именами Mother_ID и Father_ID по соглашению.

Редактировать

Если вы хотите иметь возможность создавать людей безМама и папа, вы можете сделать отношение необязательным вместо обязательного:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany();
}

Тогда внешние ключи в таблице базы данных обнуляются.

Если вы этого не сделаетекак имена столбцов по умолчанию для ваших внешних ключей (Mother_ID и Father_ID), вы можете настроить имена столбцов в вашем отображении:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany()
        .Map(m => m.MapKey("FatherID"));

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany()
        .Map(m => m.MapKey("MotherID"));
}
0 голосов
/ 31 марта 2013

Это немного странно, но вы можете сделать это без маклера modelBuilder следующим образом:

public class RecursiveModel
{
    public long Id { get; set; }
    public string Name { get; set; }

    public RecursiveModel Father { get; set; }
    public RecursiveModel Mother { get; set; }
    public ICollection<RecursiveModel> Children { get; set; }
}

Так что в основном одна из этих моделей будет иметь список своих детей, и если, например, это матькаждому из них будет присвоено значение Mother_Id и RecursiveModel_Id для этого объекта.Вам нужно будет явно подключать его каждый раз, в идеале с помощью вспомогательного метода, такого как:

    public void AddAsMotherOfChild(RecursiveModel child)
    {
        Children.Add(child);
        child.Mother = this;
    }

    public void AddAsFatherOfChild(RecursiveModel child)
    {
        Children.Add(child);
        child.Father = this;
    }

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

0 голосов
/ 05 августа 2012

Для всех, кто интересуется, это, очевидно, не может быть сделано с помощью атрибутов DataAnnotation, но может быть настроено только бегло.http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/08bba96a-20b2-4a3c-9e0e-a5475b703dfe

...