EF Core一对多还是多对多?用户<->朋友

时间:2018-11-11 10:36:24

标签: c# ef-core-2.0

我将在我的项目中实现用户友好模块。

假设我有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; }
   }

状态为枚举

这两个类的逻辑:

  • 当第一个用户邀请第二个用户加入其友谊列表时,数据库中应该创建2个对象

    user1Id: 1,
    user2Id: 2,
    Status: 1, (where 1 means 'invited')
    

    user1Id: 2,
    user2Id: 1,
    Status: 0,    (where 0 means 'nonaccepted')
    
  • 当第二个用户接受时,这2个状态将被值3更新(其中的意思是“友谊”或类似的东西-但现在不要理会逻辑了。)

我不知道如何通过代码(在C#中)创建此数据库结构

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

您的私钥必须为2 fk:user1,user2

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

我尝试过这样的事情:

    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实体导航到他的朋友(例如User.Friendship)

以及当我将导航属性添加到User类时:

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

数据库将包含四个字段:user1Id,user2Id,状态,userId

最新字段来自用户类(UsersFriendships字段)<-并且我不希望该字段出现在我的数据库中!

1 个答案:

答案 0 :(得分:2)

您可以在官方文档中找到一个示例: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)标记该属性。