.net core EF Core引用同一个表,单个集合

.net core EF Core引用同一个表,单个集合,.net-core,ef-code-first,entity-framework-core,.net Core,Ef Code First,Entity Framework Core,让我们从我想要的结果开始 我有一个成员,可以有多个舞伴。 每对舞伴都要上一门课 因此,模型的情况如下: 成员: 身份证 课程: 身份证 成员对: public class MemberPair : AuditableEntity, IEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } [Required]

让我们从我想要的结果开始

我有一个成员,可以有多个舞伴。 每对舞伴都要上一门课

因此,模型的情况如下:

成员:

  • 身份证
课程:

  • 身份证
成员对:

public class MemberPair : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid MemberId { get; set; }

    [Required]
    public Guid PartnerId { get; set; }       

    [Required]
    public Guid CourseId { get; set; }

    public Member Member { get; set; }

    public Member Partner { get; set; }

    public Course Course { get; set; }
}
  • 身份证
  • CourseId
  • 成员ID
  • 成员2id
Entityframework core为我提供了以下解决方案:

public class MemberPair : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid Member1Id { get; set; }

    [Required]
    public Guid Member2Id { get; set; }

    [Required]
    public Guid CourseId { get; set; }

    public virtual Member Member1 { get; set; }

    public virtual Member Member2 { get; set; }

    public virtual Course Course { get; set; }
}

公共类成员:AuditableEntity、Entity
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共Guid Id{get;set;}
...
公共虚拟列表伙伴{get;set;}
}
我知道理想的解决方案是无效的。但是,还有其他更好的解决方案吗? 当我迭代所有成员时,我必须找出是否必须使用MemberPairs1或MemberPairs2,我想知道这是否可以变得更简单


提前感谢。

您的评论促使我搜索其他解决方案。所以尽管你已经接受了答案,我还是想探索一些替代方案


合作伙伴的问题是,这是相对于成员的。从member1的角度来看,member2是合作伙伴,反之亦然

实现这一点的唯一方法或多或少是开箱即用,就是添加冗余数据。我的意思是从两个角度添加数据

为此,我们需要在MemberPair中包含成员:

public class MemberPair : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid MemberId { get; set; }

    [Required]
    public Guid PartnerId { get; set; }       

    [Required]
    public Guid CourseId { get; set; }

    public Member Member { get; set; }

    public Member Partner { get; set; }

    public Course Course { get; set; }
}
假设你有:

Pair1     = { Id = 1, MemberId = 1, PartnerId = 2, CourseId = 1 }
Pair1Swap = { Id = 2, MemberId = 2, PartnerId = 1, CourseId = 1 }
Pair2     = { Id = 3, MemberId = 1, PartnerId = 3, CourseId = 2 }
Pair2Swap = { Id = 4, MemberId = 3, PartnerId = 1, CourseId = 2 }
其中~ swap是冗余数据。那么

public class Member : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    // As the data is redundant only look at memberId. Check the fluent code.
    // MemberPairs should contain a list of pairs where 'this' is a member.
    // When (Member)Id == 1 then Pair1 + Pair2
    // When (Member)Id == 2 then Pair1Swap
    public ICollection<MemberPair> MemberPairs { get; set; }
}
缺点是您将有冗余数据,需要对其进行管理!但考虑到这只是一个由两人组成的团队,我认为这很容易实现,也是一个可以接受的解决方案


另一种方法是使用额外的属性(或方法,如果您愿意)扩展成员对象,以生成伙伴列表。在这种情况下,您不需要冗余数据,也不需要额外的表。但您必须同时填充两个memberPair集合

public class Member : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public List<MemberPair> MemberPairs1 { get; set; }

    public List<MemberPair> MemberPairs2 { get; set; }

    public ICollection<Member> Partners
    { 
        get
        {
            // Get all pairs where 'this' is a member.
            var pairs = MemberPairs1.Union(MemberPairs2);
            // Get all partners by filtering by Id.
            return pairs.Select(p => p.MemberId1 == Id ? p.MemberId2 : p.MemberId1);
        }
    }
}
会变成这样:

public class Pair : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid CourseId { get; set; }

    public Course Course { get; set; }

    public ICollection<PairMember> PairMembers { get; set; }
}

public class PairMember : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid PairId { get; set; }

    [Required]
    public Guid MemberId { get; set; }

    public Pair Pair { get; set; }

    public Member MemberId { get; set; }
}

public class Member : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public ICollection<PairMember> PairMembers { get; set; }
}

我想到了这个实现,所以我不得不这么做。我只是想知道ef core是否有一个很好的解决方案,其中不需要第二个表。谢谢你的邀请idea@Jim我添加了一些替代方案。
member.MemberPairs.Select(p => p.Partner);

// result for Id==1: Partner with Id 2 and Partner with Id 3.
// result for Id==2: Partner with Id 1.
public class Member : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public List<MemberPair> MemberPairs1 { get; set; }

    public List<MemberPair> MemberPairs2 { get; set; }

    public ICollection<Member> Partners
    { 
        get
        {
            // Get all pairs where 'this' is a member.
            var pairs = MemberPairs1.Union(MemberPairs2);
            // Get all partners by filtering by Id.
            return pairs.Select(p => p.MemberId1 == Id ? p.MemberId2 : p.MemberId1);
        }
    }
}
Pair:
    Id
    CourseId

PairMember:
    Id
    PairId
    MemberId
public class Pair : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid CourseId { get; set; }

    public Course Course { get; set; }

    public ICollection<PairMember> PairMembers { get; set; }
}

public class PairMember : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid PairId { get; set; }

    [Required]
    public Guid MemberId { get; set; }

    public Pair Pair { get; set; }

    public Member MemberId { get; set; }
}

public class Member : AuditableEntity, IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public ICollection<PairMember> PairMembers { get; set; }
}
member.PairMembers
        .Select(p => p.Pair.PairMembers.Where(m => m.MemberId != member.Id))