Ядро Entity Framework: Свободный API многие-ко-многим - PullRequest
0 голосов
/ 29 мая 2018

Как мне смоделировать следующее: у пользователя много подписчиков и много подписчиков.У одного и того же пользователя есть много заблокированных пользователей (функция Twitter своего рода).

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<User> Following { get; set; }
    public virtual ICollection<User> Followers { get; set; }
    public virtual ICollection<User> BlockedUsers { get; set; }
}

public class User
{
    public ApplicationUser User { get; set; }
    public string UserId { get; set; }
    public ApplicationUser Follower { get; set; }
    public string FollowerId { get; set; }
}

Моя реализация пока:

public void Configure(EntityTypeBuilder<User> builder)
{
    builder.HasKey(k => new { k.UserId, k.FollowerId });

    builder.HasOne(l => l.User)
           .WithMany(a => a.Followers)
           .HasForeignKey(l => l.UserId);

    builder.HasOne(l => l.Follower)
           .WithMany(a => a.Following)
           .HasForeignKey(l => l.FollowerId);
}

Как реализовать поле заблокированных пользователей?

public virtual ICollection<User> BlockedUsers { get; set; }

1 Ответ

0 голосов
/ 30 мая 2018

Как уже говорилось в чате, я редко доверяю возможностям EF для многим-многим, а не для EF Core.Это не прямой вопрос, а объясняет, как бы я справился с этим, если бы это был мой проект.

У вас уже есть ApplicationUser, поэтому таблицы, которые с них исходят, будут существовать только для определенияотношения между различными ApplicationUsers.Каждый пользователь может иметь несколько объектов: подписчиков, подписчиков и заблокированных.Однако пользователь не может напрямую контролировать, кто за ним следует, поэтому ему не нужна собственная таблица.Вы можете определить, кто следует за пользователем, просмотрев таблицу Follower.

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<UserFollow> Following { get; set; }
    public virtual ICollection<UserFollow> Followers { get; set; }
    public virtual ICollection<UserBlock> BlockedUsers { get; set; }
}

public class UserFollow
{
    public int Id { get; set; }

    [ForeignKey(nameof(SourceUserId))]
    public ApplicationUser SourceUser { get; set; }
    public string SourceUserId { get; set; }

    [ForeignKey(nameof(FollowedUserId))]
    public ApplicationUser FollowedUser { get; set; }
    public string FollowedUserId { get; set; }
}

public class UserBlock
{
    public int Id { get; set; }

    [ForeignKey(nameof(SourceUserId))]
    public ApplicationUser SourceUser { get; set; }
    public string SourceUserId { get; set; }

    [ForeignKey(nameof(BlockedUserId))]
    public ApplicationUser BlockedUser { get; set; }
    public string BlockedUserId { get; set; }
}

Ваша конфигурация тогда не сильно изменится (рассмотрите этот psuedo, не проверенный):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    moderlBuilder.Entity<UserFollow>()
           .HasOne(l => l.SourceUser)
           .WithMany(a => a.Following)
           .HasForeignKey(l => l.SourceUserId);

    moderlBuilder.Entity<UserFollow>()
           .HasOne(l => l.FollowedUser)
           .WithMany(a => a.Followers)
           .HasForeignKey(l => l.FollowedUserId);

    moderlBuilder.Entity<UserBlock>()
           .HasOne(l => l.SourceUser)
           .WithMany(a => a.BlockedUsers)
           .HasForeignKey(l => l.SourceUserId);
}

(примечаниеЯ всегда стучал по простому ключу (Id просто для удобства запросов), но вы можете изменить его обратно на составной при необходимости)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...