1

情况

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

餐桌俱乐部:

Id 
---

桌俱乐部2类

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 做所有事情只能正常工作,但是使用实体框架的好处应该是不必手动处理 ID。

我试过的

为了测试,我实现了两个新类并像这样修改了俱乐部类:

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 链接表中添加额外的鉴别器,以便能够区分 和 的ClubAgeCategory实例ClubPriceCategory

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

4

1 回答 1

1

对于此类问题的快速实用解决方案:如果您已经有一个现有的数据库布局设置,您可以只搭建数据库。

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

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

有关脚手架的更多信息,请参阅逆向工程(脚手架) 。

(当然,我也可以为您提供一个示例程序来解决您的实际问题,如果您不想要或可以搭建现有数据库,或者由于某种原因它没有生成您需要的内容。只需写评论。)

于 2020-11-03T14:10:48.067 回答