Можно ли напрямую ссылаться на таблицу "многие-ко-многим", используя структуру сущности, сначала код

Я использую структуру сущности и моделирующую отношение "многие ко многим".

Я создал связь между двумя объектами, используя свободный API (скажем, пользователи и группы):

this.HasMany(t => t.Users)
.WithMany(t => t.Groups)
.Map(
m =>
{
  m.ToTable("GroupMembers");
  m.MapLeftKey("Group_Id");
  m.MapRightKey("User_Id");
});

Это отлично работает, но я также хочу иметь возможность напрямую ссылаться на таблицу GroupMembers. Для этого у меня есть что-то вроде:

[Table("GroupMembers")]
public class GroupMember
{
    #region Properties

    /// <summary>
    /// Gets or sets the group.
    /// </summary>
    public virtual Group Group { get; set; }

    /// <summary>
    /// Gets or sets the Id of rht group.
    /// </summary>
    [Key]
    [Column("Group_Id", Order = 1)]
    public int GroupId { get; set; }

    /// <summary>
    /// Gets or sets the user.
    /// </summary>
    public virtual User User { get; set; }

    /// <summary>
    /// Gets or sets the Id of the user.
    /// </summary>
    [Key]
    [Column("User_Id", Order = 2)]
    public int UserId { get; set; }

    #endregion
}    

Однако при инициализации DbContext я получаю следующую ошибку:

Указанная схема недействительна. Ошибки: (381,6): ошибка 0019: EntitySet 'GroupUser' со схемой 'dbo' и table 'GroupMembers' был уже определен. Каждый EntitySet должен ссылаться на уникальную схему и таблица.

Я считаю, что это связано с тем, что инфраструктура сущности не понимает, что таблица GroupMembers, указанная в беглой API и таблице сущностей GroupMembers, фактически одна и та же. Другими словами, если я удалю свободный API-код, описывающий отношения "многие-ко-многим", я успешно смогу инициализировать DbContext.

Могу ли я иметь таблицу "многие ко многим", к которой я также могу обратиться напрямую?

Ответ 1

Нет, вы не можете. Если вы хотите иметь доступ к таблице соединений через отдельный объект, вы должны заменить отношения "многие-ко-многим" двумя отношениями "один-ко-многим" и изменить свойства навигации в User и Group для ссылки на GroupMember:

public class Group
{
    public int GroupId { get; set; }
    public virtual ICollection<GroupMember> Members { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<GroupMember> Members { get; set; }
}

modelBuilder.Entity<Group>()
    .HasMany(g => g.Members)
    .WithRequired(gm => gm.Group);

modelBuilder.Entity<User>()
    .HasMany(u => u.Members)
    .WithRequired(gm => gm.User);

Зачем вам этот объект GroupMember? Он не содержит никакого коммерческого значения и имеет только ссылки и ключи. Обычно вы можете получать и изменять любой контент таблицы соединений, записывая запросы LINQ и используя Group и User DbSets/entities и их навигационные свойства.

Ответ 2

Да, вы можете... Если вы используете другой Контекст. Если вы попытаетесь сопоставить несколько объектов с одной и той же таблицей в одном Контексте, вы получите ошибку. Но если вы поместите два сопоставления в отдельные Контексты, то проблем не будет. Таким образом, вы можете иметь одно сопоставление, которое описывает отношения многих-многих с прозрачной таблицей соединения, как если бы в нем были только внешние ключи... И вы можете иметь другое сопоставление со своим контекстом, чтобы показать фактическую таблицу соединений, если вы хотите получить какие-либо свойства отношений.

Ответ 3

Да, вы можете! Отметьте этот. Кроме того, удалите элемент GroupMembers и коллекцию IDbSet.

Ответ 4

Мы обошли это, создав представление, которое используется только для определения отношений. У нас были другие поля в таблице поиска, которые нам нужны для доступа.

Вид просто выбирает поля соединения из таблицы поиска.