EF Code First - WithMany () - PullRequest
       2

EF Code First - WithMany ()

12 голосов
/ 08 мая 2011

Я недавно пришел в класс ManyNavigationPropertyConfiguration<TEntity, TTarget> и внутри этого класса я нашел метод с именем WithMany() с двумя перегрузками.

Первая перегрузка: WithMany()

Конфигурирует отношения, которые будут многие: многие без навигации собственность на другой стороне отношения.

Вторая перегрузка: WithMany(Expression<Func<TTarget, ICollection<TEntity>>>)

Конфигурирует отношения, которые будут многие: многие со свойством навигации на другой стороне отношений.

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

Ответы [ 2 ]

35 голосов
/ 08 мая 2011

Примером может быть эта модель:

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
    public ICollection<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public string Description { get; set; }
}

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

public ICollection<User> Users { get; set; }

... классу Role было бы ненужными накладными расходами.

Но вы все равно должны EF сказать, что существует отношение многие ко многим между User и Role...

modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithMany();

... потому что сопоставления соглашения по умолчанию создали бы неправильное отношение, а именно отношение один ко многим, соответствующее этому отображению:

modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithOptional();
5 голосов
/ 08 мая 2011

Обратите внимание, что для свойства навигации выбрано на другой стороне цели .

Давайте рассмотрим пример, хотя этот конкретный случай может не быть идеальным иллюстратором моей точки зрения ... Если вы хотите отслеживать математические тесты и повторно использовать вопросы, у вас может быть две таблицы (Tests и Questions) которые имеют отношения многие ко многим; В каждом тесте есть несколько вопросов, и каждый вопрос может появляться в нескольких тестах. Однако вам, возможно, никогда не понадобится получить набор тестов, на которых задан конкретный вопрос - даже если вы знаете, что вопросы могут появляться в более чем одном тесте, вас это не интересует.
Таким образом, вы используете перегрузку .WithMany() при объявлении этого, поэтому вы получаете навигационное свойство для получения вопросов теста (theTest.Questions()), но не обладаете навигационным свойством в другом случае (theQuestion.Tests()). Но вам все еще нужны отношения «многие ко многим», так как и тесты, и вопросы могут иметь множество других.
Я согласен, что в данном конкретном случае эта настройка может не иметь смысла, но, безусловно, есть случаи, когда это происходит, и в этих случаях перегрузка .WithMany() позволяет обойтись без определения свойств (и лямбда-выражения для каждого из них) вам никогда не понадобится.

...