Ну, 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 заключается в том, что вы можете контролировать имя таблицы ссылок (и ключимена столбцов).Вы не можете определить эти имена с аннотациями данных.