流利的API-带有鉴别符的多对多

问题描述

情况

我们在MysqL中具有以下表(我们不能更改表布局或添加新表)。

桌俱乐部:

Id 
---

Table club2类别

ClubId | CategoryId
-------+-----------

表格类别

Id | TypeIdentifier
---+----------------

当前有两种类型的类别:AgeCategory和PriceCategory。

以下是所需的C#类结构。

类别:

public abstract class CategoryBase
{
    public int Id { get; set; }

    public string TypeIdentifier { get; set; }

    public IList<Club> Clubs { get; set; }

    private protected CategoryBase() { }

    private protected CategoryBase(string typeIdentifier)
    {
        TypeIdentifier = typeIdentifier;
    }
}

public class AgeCategory
{
    private AgeCategory()
    {
    }

    public AgeCategory() : base("AGE")
    {
    }
}

public class PriceCategory : CategoryBase
{
    private PriceCategory()
    {
    }

    public PriceCategory() : base("PRICE")
    {
    }
}

俱乐部:

public class Club
{
    public int Id { get; set; }
    
    public IList<PriceCategory> PriceCategories { get; set; }
    
    public AgeCategory AgeCategory { get; set; }
    
    private Club()
    {
    }
}

链接表:

public class ClubCategory
{
    public int ClubId { get; set; }

    public int CategoryId { get; set; }

    public Club Club { get; set; }
    
    public CategoryBase Category { get; set; }
}

问题

但是,我们不确定如何使用Fluent API进行导航属性映射,因为我们基本上在表俱乐部和表类别之间具有一对多和多对多的关系。使用数据库ID进行所有操作都只能正常工作,但是使用Entity Framework的好处应该是不必手动处理ID。

我尝试过的事情

为了进行测试,我实现了两个新类并修改了Club类,如下所示:

public class ClubAgeCategory : ClubCategory
{
    public virtual AgeCategory AgeCategory { get; set; }
}

public class ClubPriceCategory : ClubCategory
{
    public virtual PriceCategory PriceCategory { get; set; }
}

public class Club
{
    public int Id { get; set; }
    
    public IList<ClubPriceCategory> PriceCategoryLinkers { get; set; }
    
    public ClubAgeCategory AgeCategoryLinker { get; set; }
    
    private Club()
    {
    }
}

然后我试图像这样设置映射

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // ....
    #region ClubAgeCategory

    modelBuilder.Entity<ClubAgeCategory>()
        .HasOne(cac => cac.Club)
        .WithOne(c => c.AgeCategoryLinker)
        .HasForeignKey<ClubAgeCategory>(cac => cac.ClubId)
        .OnDelete(DeleteBehavior.Cascade);

    modelBuilder.Entity<ClubAgeCategory>()
        .HasOne(cac => cac.AgeCategory)
        .WithMany(ac => ac.ClubLinkers)
        .HasForeignKey(cac => cac.CategoryId)
        .OnDelete(DeleteBehavior.Cascade);

    #endregion

    #region ClubPriceCategory

    modelBuilder.Entity<ClubPriceCategory>()
        .HasOne(cpc => cpc.Club)
        .WithMany(c => c.PriceCategoryLinkers)
        .HasForeignKey(cpc => cpc.ClubId)
        .OnDelete(DeleteBehavior.Cascade);

    modelBuilder.Entity<ClubPriceCategory>()
        .HasOne(cpc => cpc.PriceCategory)
        .WithMany(pc => pc.ClubLinkers)
        .HasForeignKey(cpc => cpc.CategoryId)
        .OnDelete(DeleteBehavior.Cascade);

    #endregion
    // ....
}

但是,现在我需要在club2category链接表中具有其他区分符,以便能够区分ClubAgeCategoryClubPriceCategory的实例。

在这一点上,我不知道您将如何实现这样的目标。任何帮助将不胜感激。

解决方法

一般来说,这样的问题的快速实用解决方案:如果您已经有一个现有的数据库布局设置,则只需搭建数据库即可。

dotnet ef dbcontext scaffold "server=127.0.0.1;uid=root;pwd=myPassword;port=3306;database=So64662261" Pomelo.EntityFrameworkCore.MySql -c Context -o Models --verbose

脚手架将生成使用现有数据库所需的完整代码。

有关脚手架的更多信息,请参见Reverse Engineering (scaffolding)

(当然,如果您不想要或可以支撑现有数据库,或者由于某种原因它不能生成所需的内容,我当然也可以为您提供示例程序,只需编写注释即可。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...