【问题标题】:Entity Framework Core: Fluent api many-to-manyEntity Framework Core:Fluent api 多对多
【发布时间】:2018-11-07 23:39:35
【问题描述】:

我如何建模以下内容:一个用户有很多关注者并关注了很多用户。同一个用户有很多被屏蔽的用户(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; }

【问题讨论】:

  • 你能解释一下为什么你有UserApplicationUser吗? User 类的用途是什么?
  • User 似乎是一个代表关注者/关注链接的多对多链接实体。因此,对于 Blocked / Blocking 链接,您需要一个 separate 类似的链接实体。
  • @DavidKemp 就像 Ivan 说的,用户是一个链接,它就像一个 join 表。 ApplicationUser 是一个扩展 IdentyUser 并向 AspNetUsers 表添加额外属性(列)的类。
  • 这可能是审查文档的工作:docs.microsoft.com/en-us/ef/core/modeling/…,但就像@IvanStoev 所说,你需要另一个class

标签: c# asp.net asp.net-core entity-framework-core


【解决方案1】:

正如聊天中所讨论的,我很少相信 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; }
}

然后您的配置并没有太大变化(考虑这个伪,未经测试):

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 只是为了便于查询),但您可以根据需要将其改回复合键)

【讨论】:

  • 我如何在 Likes Table 中命名属性?喜欢和喜欢还是什么??
猜你喜欢
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2011-04-06
相关资源
最近更新 更多