Как я могу использовать EF Code First для объявления отношения один ко многим? - PullRequest
7 голосов
/ 20 марта 2011

Я пытаюсь определить простое отношение «один ко многим» между двумя poco's , используя свободный API Entity Framework.

~ Team ~
public int TeamId { get; set; }
public ICollection<User> TeamMembers { get; set; } // All the team players. Two way nav.
public Player CreatedBy { get; set; } // Which player created this team. One way navigation.
                                      // Optional. Not all players create a team.

~ Player ~
public int PlayerId { get; set; }
public Team Team { get; set; } // The other side of the TeamMembers navigation.

ПРИМЕЧАНИЯ:

  • Игроку не обязательно быть в команде.(Неназначенные / отброшенные игроки).
  • В команде не может быть игроков (у них все осталось / уволились).

Ближайшее, что я получил, было что-то вроде этого ...

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Team>()
        .HasOptional(x => x.TeamMembers)
        .WithMany()
        .WillCascadeOnDelete(false);
}

... Что не работает ... и я не уверен, как определить другие навигационные элементы.

Может кто-нибудь помочь, пожалуйста?

Ответы [ 2 ]

12 голосов
/ 20 марта 2011

Я думаю, что эта объектная модель - то, что вы ищете:

public class Team
{    
    public int TeamId { get; set; }
    public ICollection<Player> TeamMembers { get; set; } 
    public Player CreatedBy { get; set; } 
}

public class Player
{
    public int PlayerId { get; set; }
    public Team Team { get; set; } 
}       

public class Context : DbContext
{
    public DbSet<Player> Players { get; set; }
    public DbSet<Team> Teams { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Player>()
                    .HasOptional(p => p.Team)
                    .WithMany(t => t.TeamMembers)
                    .Map(c => c.MapKey("TeamId"));

        // Or alternatively you could start from the Team object:
        modelBuilder.Entity<Team>()
                    .HasMany(t => t.TeamMembers)
                    .WithOptional(p => p.Team)
                    .Map(c => c.MapKey("TeamId"));
    }
}

Кстати, следующий свободный код API, который вы используете, неверен:

...HasOptional(x => x.TeamMembers)

Потому что TeamMembersявляется коллекцией и не может использоваться HasOptional методом, который всегда должен вызываться с одним объектом.

Обновление - HasRequired против HasOptional:

Хотя они оба установленыв сопоставлении они дают несколько разные результаты и предъявляют различные требования:

  • Если это сопоставление FK (свойство FK предоставляется зависимому объекту), тогда оно должно иметь тип NULL, еслипри использовании HasOptional и ненулевого типа при использовании HasRequired или будет выдан Code First.

  • Code First автоматически включит каскадное удаление при использовании HasRequired метод.

  • Другое отличие заключается в поведении во время выполнения EF, когда дело доходит до удаления.Рассмотрим сценарий, в котором мы хотим удалить главный объект (например, Team), пока у него есть зависимый объект (например, Player), а каскадное удаление отключено.С помощью HasOptional среда выполнения EF автоматически обновит зависимый столбец FK до нуля, а с HasRequired EF сгенерирует запрос и попросит вас либо явно удалить зависимый объект, либо связать его с другим основным объектом (еслиесли вы хотите попробовать это, вы должны знать, что в обоих случаях и главный, и зависимый объекты должны быть уже загружены в контексте, чтобы EF отслеживал их).

2 голосов
/ 20 марта 2011

Я смог заставить это работать автоматически, просто сделав что-то вроде этого:

 public class Team {
    public int TeamId { get; set; }
    ...
    public virtual ICollection<Player> Players { get; set; }
}

Но вам нужно будет более точно определить, что именно вы имеете в виду, когда говорите «не работает». Что не работает, точно? Вы получаете сообщение об ошибке? Если так, то, что это? Всегда ли свойство Team объекта Player возвращает ноль?

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