C# 当我需要具有相同类型的多个关系时,实体框架会出现问题

C# 当我需要具有相同类型的多个关系时,实体框架会出现问题,c#,sql,entity-framework,C#,Sql,Entity Framework,这个问题困扰了我一段时间,如果能得到任何帮助,我将不胜感激 假设我有两个类,用户和房间,基本上是这样的 public class User { [Key] public int UserId {get; set;} public string Username {get; set;} public virtual List<Room> Rooms {get; set;} } public class Room { [Key] publ

这个问题困扰了我一段时间,如果能得到任何帮助,我将不胜感激

假设我有两个类,用户和房间,基本上是这样的

public class User
{
    [Key]
    public int UserId {get; set;}
    public string Username {get; set;}
    public virtual List<Room> Rooms {get; set;}
}

public class Room
{
    [Key]
    public int RoomId {get; set;}
    [ForeignKey("Owner")] // have tried with and without the explicit relationship
    public int OwnerId {get; set;}
    public User Owner {get; set; }
    public virtual List<User> Members {get; set;}
}
公共类用户
{
[关键]
public int UserId{get;set;}
公共字符串用户名{get;set;}
公共虚拟列表室{get;set;}
}
公共教室
{
[关键]
public int RoomId{get;set;}
[ForeignKey(“Owner”)]//已尝试使用或不使用明确关系
public int OwnerId{get;set;}
公共用户所有者{get;set;}
公共虚拟列表成员{get;set;}
}
我的希望是建立一个s结构,允许用户拥有多个房间,其中他们是所有者,但也可以作为成员包含在多个房间中

当我实际尝试创建一个房间并添加成员时,问题就出现了。将添加所有者属性,但成员列表始终为空

我正在使用注释API,但也尝试了fluent API

当我尝试这个方法时,我得到了一个多重性错误

 modelBuilder.Entity<Room>()
                .HasMany(t => t.Members).WithMany(u => u.Rooms);
modelBuilder.Entity()
.有许多(t=>t.成员)。有许多(u=>u.房间);
我相信答案很简单,我只是不太擅长实体。任何帮助都将不胜感激


感谢

如果您正在使用EF Core创建多对多,这就是您所追求的,您需要另一个实体,
UserRoom
,它包含一对多的
用户
和一对多的
房间
,如:

public class UserRoom
{
    public int UserId { get; set; }
    public User User { get; set; }
    public int RoomId { get; set; }
    public Room Room { get; set; }    
}
然后在
用户中

    [InverseProperty(nameof(UserRoom.User))]
    public ICollection<UserRoom> UserRooms { get; set; }
在您的情况下,听起来您需要两种多对多关系—一种是房间成员关系,另一种是房间所有权关系。在这种情况下,您将需要两次实现此模式,链接实体可能更合适地命名为OwnerRoom和MemberRoom

如果房间所有权对于单个用户是唯一的,那么您需要MemberRoom和上面的模式,以及与房间和用户的标准1对多关系,就像您已经实现的那样,只需使用以下内容装饰
user.Rooms


[InverseProperty(nameof(Room.Owner))]

如果您使用EF Core,要创建多对多,这就是您所追求的,您需要另一个实体,
UserRoom
,它包含一对多的
用户
和一对多的
Room
,如:

public class UserRoom
{
    public int UserId { get; set; }
    public User User { get; set; }
    public int RoomId { get; set; }
    public Room Room { get; set; }    
}
然后在
用户中

    [InverseProperty(nameof(UserRoom.User))]
    public ICollection<UserRoom> UserRooms { get; set; }
在您的情况下,听起来您需要两种多对多关系—一种是房间成员关系,另一种是房间所有权关系。在这种情况下,您将需要两次实现此模式,链接实体可能更合适地命名为OwnerRoom和MemberRoom

如果房间所有权对于单个用户是唯一的,那么您需要MemberRoom和上面的模式,以及与房间和用户的标准1对多关系,就像您已经实现的那样,只需使用以下内容装饰
user.Rooms


[InverseProperty(nameof(Room.Owner))]

用户
房间
之间有两种关系:

    [InverseProperty(nameof(UserRoom.Room))]
    public ICollection<UserRoom> UserRooms { get; set; }
  • 用户为所有者的房间(
    一对多
  • 用户是成员的房间(
    多对多
单个
房间
集合不能表示这两个关系,您需要两个集合:

public class User
{
    [Key]
    public int UserId {get; set;}
    public string Username {get; set;}
    public virtual List<Room> OwnerOfRooms {get; set;}
    public virtual List<Room> MemberOfRooms {get; set;}
}
公共类用户
{
[关键]
public int UserId{get;set;}
公共字符串用户名{get;set;}
公共虚拟列表所有者Rooms{get;set;}
公共虚拟列表MemberOfRoom{get;set;}
}
并使用以下Fluent配置:

modelBuilder.Entity<User>()
    .HasMany(u => u.OwnerOfRooms)
    .WithRequired(r => r.Owner)
    .HasForeignKey(r => r.OwnerId);

modelBuilder.Entity<User>()
    .HasMany(u => u.MemberOfRooms)
    .WithMany(r => r.Members);
modelBuilder.Entity()
.HasMany(u=>u.OwnerOfRooms)
.WithRequired(r=>r.Owner)
.HasForeignKey(r=>r.OwnerId);
modelBuilder.Entity()
.HasMany(u=>u.MemberOfRoom)
.有许多(r=>r.成员);

请注意,第二个关系将创建自动连接表
UserRooms

您在
User
rooms
之间有两个关系:

    [InverseProperty(nameof(UserRoom.Room))]
    public ICollection<UserRoom> UserRooms { get; set; }
  • 用户为所有者的房间(
    一对多
  • 用户是成员的房间(
    多对多
单个
房间
集合不能表示这两个关系,您需要两个集合:

public class User
{
    [Key]
    public int UserId {get; set;}
    public string Username {get; set;}
    public virtual List<Room> OwnerOfRooms {get; set;}
    public virtual List<Room> MemberOfRooms {get; set;}
}
公共类用户
{
[关键]
public int UserId{get;set;}
公共字符串用户名{get;set;}
公共虚拟列表所有者Rooms{get;set;}
公共虚拟列表MemberOfRoom{get;set;}
}
并使用以下Fluent配置:

modelBuilder.Entity<User>()
    .HasMany(u => u.OwnerOfRooms)
    .WithRequired(r => r.Owner)
    .HasForeignKey(r => r.OwnerId);

modelBuilder.Entity<User>()
    .HasMany(u => u.MemberOfRooms)
    .WithMany(r => r.Members);
modelBuilder.Entity()
.HasMany(u=>u.OwnerOfRooms)
.WithRequired(r=>r.Owner)
.HasForeignKey(r=>r.OwnerId);
modelBuilder.Entity()
.HasMany(u=>u.MemberOfRoom)
.有许多(r=>r.成员);

请注意,第二个关系将在您给我们的
代码中创建自动连接表
UserRooms

。HasMany(t=>t.Users)
的属性名称与
rooms
类上的
成员的属性名称不同。@krillgar,是的,对不起,我从实际代码中重命名了几个字段,试图让我的意图更清楚,但我错过了那个字段。感谢您给我们的代码。HasMany(t=>t.Users)
的属性名与
Room
类中的
成员的属性名不同。@krillgar,是的,很抱歉,我从实际代码中重命名了几个字段,试图让我的意图更清楚,但我错过了那个字段。谢谢这看起来像我需要的,但是当我尝试添加它时,我仍然会得到多重性错误。WillCascadeOnDelete(false)到第一个函数,工作得很好(我认为)这看起来像我需要的,但是当我尝试添加它时,我仍然会得到多重性错误。WillCascadeOnDelete(false)到第一个函数,工作得很好(我认为)