首页 > 解决方案 > EF Core 中的零或一关系

问题描述

我在 EF Core 中有一个零或一关系的特殊场景,默认情况下无法轻松建模(如EF Core 一对一或零关系中所述)。

我有多个实体与“匹配”实体具有 0-1 关系。多个实例可以引用同一个“匹配”实体(这就是为什么我不能将外键放入“匹配”表的原因,这似乎是建模 0-1 关系的推荐方式)。

如何定义从实体之一到 0-1“匹配”实体的关系?我必须创建一个 Match().HasMany(someKindOfBaseClassOfEntities) 吗?有没有更好的办法?

标签: c#entity-frameworkentity-framework-coreef-core-5.0

解决方案


您可以使用 来配置它HasOne,它允许 1:0..1 关系。仅展示一种无需重复太多映射代码的方法:

课程:

class Match
{
    public int ID { get; set; }
    public string Name { get; set; }
}

abstract class HasMatchBase
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int? MatchID { get; set; }
    public Match Match { get; set; }
}

class A : HasMatchBase
{
    public string Code { get; set; } // Just an example
}

class B : HasMatchBase { }

映射配置:

abstract class HasMatchBaseConfig<T> : IEntityTypeConfiguration<T>
    where T : HasMatchBase
{
    public void Configure(EntityTypeBuilder<T> builder)
    {
        builder.Property(b => b.Name).HasMaxLength(200);
        builder.HasOne(b => b.Match).WithOne().HasForeignKey<T>(b => b.MatchID);

        ConfigureMatchOwner(builder);
    }
    
    public abstract void ConfigureMatchOwner(EntityTypeBuilder<T> builder);
}

class AConfig : HasMatchBaseConfig<A> 
{ 
    public override void ConfigureMatchOwner(EntityTypeBuilder<A> builder)
    {
        builder.Property(a => a.Code).HasColumnType("CHAR").HasMaxLength(3);
        ... // Further A-specific mapping
    }
}

class BConfig : HasMatchBaseConfig<B>
{
    public override void ConfigureMatchOwner(EntityTypeBuilder<B> builder)
    {
        ... // B-specific mapping. 
    }
}

的类型HasMatchBase.MatchID确定关联是必需的还是可选的。在这种情况下,它是一个 nullable int,将关联变成Match可选的。


推荐阅读