C# EF核心一对多还是多对多?用户<--&燃气轮机;朋友

C# EF核心一对多还是多对多?用户<--&燃气轮机;朋友,c#,ef-core-2.0,C#,Ef Core 2.0,我将在我的项目中实现一个用户朋友模块 假设我有两个简单的类: public class User { int Id { get; set; } string Name { get; set; } } 和友谊类(用户之间的关系) 状态为枚举 这两类的逻辑: 当第一个用户邀请第二个用户加入他的友谊列表时,数据库中应该创建两个对象 user1Id: 1, user2Id: 2, Status: 1, (where 1 means 'invited') 及 当第二个用户接受时,这

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

假设我有两个简单的类:

public class User
{
    int Id { get; set; }
    string Name { get; set; }
}
和友谊类(用户之间的关系)

状态为枚举

这两类的逻辑:

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

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

  • 当第二个用户接受时,这2个状态将被值3更新(这里的意思是“友谊”或类似的东西-但是现在忘记逻辑

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

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

私钥必须是2 fk:user1,user2

问题是,这两个外键都指向一个表(用户)

我试过这样的方法:

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

    modelBuilder.Entity<UsersFriendship>()
        .HasMany(x=> x.Users)
        .WithOne(x=>x.UsersFriendships)
   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; }
    }
最简单的方法是键入模型生成器:

 modelBuilder.Entity<UsersFriendship>()
        .HasKey(x => new { x.User1Id, x.User2Id });
但从现在起,我不能从用户实体导航到他的朋友(比如User.friends)

当我向用户类添加导航属性时:

public virtual List<UsersFriendship> UsersFriendships { get; set; }
公共虚拟列表用户friendships{get;set;}
数据库将包含四个字段:user1Id、user2Id、status、userId


最新字段来自用户类(UsersFriendships字段)您可以在官方文档中找到一个示例:

我调整了此示例以反映您的情况:

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);
      }
  }
名称空间foo
{
公共类用户
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟列表用户friendships{get;set;}
}
公众阶级友谊
{
公共用户User1{get;set;}
public int User1Id{get;set;}
公共用户User2{get;set;}
public int User2Id{get;set;}
公共int状态{get;set;}
}
类MyContext:DbContext
{
公共数据库集友谊{get;set;}
公共数据库集用户{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(fs=>new{fs.User1,fs.User2,fs.Status});
modelBuilder.Entity()
.HasOne(fs=>fs.User1)
.有许多(u=>u.UsersFriendships)
.HasForeignKey(fs=>fs.User1);
modelBuilder.Entity()
.HasOne(fs=>fs.User2)
.有许多(u=>u.UsersFriendships)
.HasForeignKey(fs=>fs.User2);
}
}

最新的字段来自用户类(UsersFriendships字段),顺便说一句,我假设你的朋友不是船(在
类友谊中用小写字母写“ship”)“这个解决方案对我不起作用。相反,我找到了一个类似问题的以下答案,为我解决了多对多自我参考问题:"你确定吗?我更新了我的示例以匹配你的问题。请再次检查。很抱歉,在此期间,我更新了我的帖子。现在,你的示例与我的一样,使用我认为的属性。但是我不知道我该怎么做才能在Userclass中拥有导航属性,但在数据库中没有附加字段是不起作用的。你需要两个public虚拟列表
   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; }
    }
public virtual List<UsersFriendship> UsersFriendships { get; set; }
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);
      }
  }