如何配置多对多关系,其中一侧在 ef core 中有 2 个集合

问题描述 投票:0回答:1

所以正如标题所说,我有以下实体:

public class Group
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Link> Links { get; set; }
}

public class Link
{
    public int Id { get; set; }
    public List<Group> SourceGroups { get; set; }
    public List<Group> DestinationGroups { get; set; }
}

我想在它们之间建立多对多的关系。 问题在于我在 Link 实体中有 2 个集合,因此 ef core 必须知道它是源还是目标。

我尝试添加一个值来确定该组是自定义连接实体的源还是目标:

public class LinkGroup
{
    public int LinkId { get; set; }
    public int GroupId { get; set; }
    public bool IsSource { get; set; }
}

但是我找不到一种方法来配置 ef core 以自动使用 IsSource 值并将正确的值填充到正确的集合中。

我还尝试创建 2 个不同的连接实体并分别配置每个实体:

public class LinkDestinationGroup
{
    public int LinkId { get; set; }
    public int GroupId { get; set; }
}

public class LinkSourceGroup
{
    public int LinkId { get; set; }
    public int GroupId { get; set; }
}

使用大致如下所示的 OnModelCreating:

public override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Link>().HasMany(e => e.SourceGroups).WithMany(e => e.Links).UsingEntity<LinkSourceGroup>();
    modelBuilder.Entity<Link>().HasMany(e => e.DestinationGroups).WithMany(e => e.Links).UsingEntity<LinkDestinationGroup>();
}

但是我在 ef core 端遇到了错误。

c# asp.net .net entity-framework-core backend
1个回答
0
投票

对于这种情况使用两个单独的表可以解决问题:

组:

public class Group
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<LinkDestinationGroup> DestinationGroups { get; set; }
    public virtual List<LinkSourceGroup> SourceGroups { get; set; }
}

链接:

public class Link
{
    public int Id { get; set; }
    public virtual List<LinkDestinationGroup> DestinationGroups { get; set; }
    public virtual List<LinkSourceGroup> SourceGroups { get; set; }
}

链接目标组:

public class LinkDestinationGroup
{
    public int LinkId { get; set; }
    public int GroupId { get; set; }
    
    public virtual Link Link { get; set; }
    public virtual Group Group { get; set; }
}

链接源组

public class LinkSourceGroup
{
    public int LinkId { get; set; }
    public int GroupId { get; set; }
    
    public virtual Link Link { get; set; }
    public virtual Group Group { get; set; }
}

链接目标组配置:

public class LinkDestinationGroupConfiguration : IEntityTypeConfiguration<LinkDestinationGroup>
{
    public void Configure(EntityTypeBuilder<LinkDestinationGroup> builder)
    {
        builder.HasOne(c => c.Link)
            .WithMany(c => c.DestinationGroups)
            .HasForeignKey(c => c.LinkId);
        builder.HasOne(c => c.Group)
            .WithMany(c => c.DestinationGroups)
            .HasForeignKey(c => c.GroupId);
    }
}

链接源组定义:

    public void Configure(EntityTypeBuilder<LinkSourceGroup> builder)
    {
        builder.HasOne(c => c.Link)
            .WithMany(c => c.SourceGroups)
            .HasForeignKey(c => c.LinkId);
        builder.HasOne(c => c.Group)
            .WithMany(c => c.SourceGroups)
            .HasForeignKey(c => c.GroupId);
    }

旁注:

导航属性使用“virtual”关键字定义,用于延迟配置,请参阅 => https://learn.microsoft.com/en-us/ef/core/modeling/relationships/navigations

Fluent-Api 用于配置实体,请参阅 => https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/ Fluent/types-and-properties

另外不要忘记在 dbcontext 的 OnModelCreating 方法中调用这些配置,如下所示:

protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
      builder.ApplyConfigurationsFromAssembly(typeof(FooDbContext).Assembly);
    }
© www.soinside.com 2019 - 2024. All rights reserved.