【问题标题】:EF Core one-to-many or many-to-many ? users<-->friendsEF Core 一对多还是多对多?用户<-->朋友
【发布时间】:2019-04-14 07:57:52
【问题描述】:

我将在我的项目中实现一个用户朋友模块。

假设我有 2 个简单的类

public class User
{
    int Id { get; set; }
    string Name { get; set; }
}

和FriendShip类(用户之间有关系):

public class FriendShip
{
    int User1Id { get; set; }
    int User2Id { get; set; }
    int Status  { get; set; }
}

状态类型为Enum

这两个类的逻辑

  • 当第一个用户邀请第二个用户加入他的好友列表时,应该在数据库中创建 2 个对象
user1Id: 1,
user2Id: 2,
Status: 1, (where 1 means 'invited')

user1Id: 2,
user2Id: 1,
Status: 0,    (where 0 means 'nonaccepted')
  • 当第二个用户接受时,这 2 个状态将通过值 3 更新(其中表示“友谊”或类似的东西 - 但现在忘记逻辑。

我不知道如何设计数据库。

这将是一对多的,就像一个用户可以与其他用户有许多关系?

私钥必须是2个外键:user1,user2

问题是这两个外键进入一个表(用户)

我试过这样的

modelBuilder.Entity<User>()
    .HasMany(x => x.UsersFriendships)
    .WithOne(x => x.User2)

modelBuilder.Entity<UsersFriendship>()
    .HasMany(x => x.Users)
    .WithOne(x => x.UsersFriendships)

但这没有意义,我不能做第二个陈述

.WithOne(x => x.userFriendships)

最简单的方法是输入模型生成器

modelBuilder.Entity<UsersFriendship>()
   .HasKey(x => new { x.User1Id, x.User2Id });

UserFriendship 类:

public class UsersFriendship 
{
    [ForeignKey("User1Id")]
    public User User1 { get; set; }

    [ForeignKey("User2Id")]
    public User User2 { get; set; }

    public int User1Id { get; set; }
    
    public int User2Id { get; set; }
    
    public RelationStatus RelationStatus { get; set; }
}

但是从现在开始,我无法从用户实体导航到他的朋友(例如User.Friendship

当我将导航属性添加到用户类 :

public virtual List<UsersFriendship> UsersFriendships { get; set; }

数据库会有四个字段:user1Id、user2Id、status、userId

最新的字段来自用户类(UsersFriendships 字段)

【问题讨论】:

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


【解决方案1】:

您可以在官方文档中找到一个示例:https://docs.microsoft.com/en-us/ef/core/modeling/relationships#many-to-many

我调整了这个例子来反映你的情况:

namespace foo
{
  public class User
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<UsersFriendship> UsersFriendships { get; set; }
  }

  public class Friendship
  {
      public User User1 { get; set; }
      public int User1Id { get; set; }
      public User User2 { get; set; }
      public int User2Id { get; set; }
      public int Status  { get; set; }
  }

  class MyContext : DbContext
  {
      public DbSet<Friendship> Friendships { get; set; }
      public DbSet<User> Users { get; set; }

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Friendship>()
              .HasKey(fs => new { fs.User1, fs.User2, fs.Status });

          modelBuilder.Entity<Friendship>()
              .HasOne(fs => fs.User1)
              .WithMany(u => u.UsersFriendships)
              .HasForeignKey(fs => fs.User1);

          modelBuilder.Entity<Friendship>()
              .HasOne(fs => fs.User2)
              .WithMany(u => u.UsersFriendships)
              .HasForeignKey(fs => fs.User2);
      }
  }

最新的字段来自用户类(UsersFriendships 字段)

当将此注册为导航属性时(请参阅我的代码),它将不会存储在 db 中。

在其他情况下,如果出于某种原因您不希望 ef core 将属性存储在 db 中,请使用 [NotMapped] 属性 (namespace System.ComponentModel.DataAnnotations.Schema) 标记该属性。

【讨论】:

  • 你确定吗?我更新了我的示例以匹配您的问题。请再次检查。
  • 很抱歉,但与此同时我已经更新了我的帖子。现在你的例子和我的想法一样,我认为有属性。但我不知道我应该怎么做才能在 Userclass 中拥有导航属性,但在数据库中没有额外的字段
  • 不起作用。您需要两个公共虚拟 List
猜你喜欢
  • 2019-07-17
  • 2017-10-26
  • 1970-01-01
  • 2020-11-19
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 2021-10-11
相关资源
最近更新 更多