Код EF первый-WithMany()
Я недавно пришел в класс ManyNavigationPropertyConfiguration<TEntity, TTarget>
, и в этом классе я нашел метод с именем WithMany()
С 2 перегрузками.
первая перегрузка:
WithMany()
настраивает отношения много:много без навигации собственность на другой стороне отношение.
вторая перегрузка:
WithMany(Expression<Func<TTarget, ICollection<TEntity>>>)
настраивает отношения многие: многие со свойством навигации с другой сторона отношений.
теперь мой вопрос, почему вы настраиваете отношение на много:много без свойства навигации (первая перегрузка)? Я не вижу никаких сценариев, где это было бы полезно... Есть мысли?
2 ответов
примером может быть эта модель:
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();
обратите внимание, что выбор для свойства навигации является на другой стороне мишени.
давайте рассмотрим пример, хотя этот конкретный случай может не быть идеальным иллюстратором моей точки зрения... Если вы хотите отслеживать математические тесты и повторно использовать вопросы, у вас может быть две таблицы (Tests
и Questions
), которые имеют отношение "многие ко многим"; каждый тест имеет несколько вопросов, и каждый вопрос может отображаться на нескольких тестах. Тем не менее, вы можете никогда нужно получить набор тестов, на которых находится конкретный вопрос - даже если вы знаете, что вопросы могут появляться на более чем одном тесте, вас не интересует, какой.
Таким образом, вы используете .WithMany()
перегрузка при объявлении этого, поэтому вы получаете навигационное свойство для получения вопросов теста (theTest.Questions()
), но нет навигационного свойства в другую сторону (theQuestion.Tests()
). Но вам все равно нужны отношения "многие ко многим", так как и тесты, и вопросы могут иметь много других.
Я согласен, что в в этом конкретном случае эта настройка может не иметь смысла, но есть, конечно, случаи, когда это происходит, и в этих случаях .WithMany()
overload позволяет вам обойтись без определения свойств (и лямбда-выражения для каждого из них), которые вам никогда не понадобятся.