Ответ 1
Ну, у EF нет какого-то алгоритма распознавания слова и грамматики, который должен был бы определить, что вы (возможно) хотите, чтобы User.Residencies
и Town.Residents
сформировали пару навигационных свойств и User.Mayorships
и Town.Mayors
образуют вторую пару. Поэтому предполагается, что у вас есть четыре отношения "один ко многим" и каждое из четырех свойств навигации относится к одному из отношений. (Это причина четырех внешних ключей, которые вы видели в таблицах базы данных.)
Это стандартное предположение не то, что вы хотите, поэтому вы должны явно определить отношения, чтобы переопределить это стандартное соглашение:
Либо с аннотациями данных:
public class User
{
[Key]
public long UserId { get; set; }
[Required]
public String Nickname { get; set; }
[InverseProperty("Residents")]
public virtual ICollection<Town> Residencies { get; set; }
[InverseProperty("Mayors")]
public virtual ICollection<Town> Mayorships { get; set; }
}
Или с Fluent API:
modelBuilder.Entity<User>()
.HasMany(u => u.Residencies)
.WithMany(t => t.Residents)
.Map(x =>
{
x.MapLeftKey("UserId");
x.MapRightKey("TownId");
x.ToTable("TownResidents");
});
modelBuilder.Entity<User>()
.HasMany(u => u.Mayorships)
.WithMany(t => t.Mayors)
.Map(x =>
{
x.MapLeftKey("UserId");
x.MapRightKey("TownId");
x.ToTable("TownMayors");
});
Fluent API имеет то преимущество, что вы можете управлять именем таблицы ссылок (а также именами столбцов клавиш). Вы не можете определить эти имена с аннотациями данных.