C# 如何在EF Core 5 Fluent API中配置具有继承关系的值对象
我有一个包含聚合a的DDD项目,它有一个实体列表属性列表,实体B中有一个值对象C,代码如下:C# 如何在EF Core 5 Fluent API中配置具有继承关系的值对象,c#,inheritance,entity-framework-core,ef-fluent-api,value-objects,C#,Inheritance,Entity Framework Core,Ef Fluent Api,Value Objects,我有一个包含聚合a的DDD项目,它有一个实体列表属性列表,实体B中有一个值对象C,代码如下: public class A { public Guid Id {get; protected set;} public List<B> Bs {get; protected set;} } public class B { public Guid Id {get; protected set;} public C C {get; protected set
public class A
{
public Guid Id {get; protected set;}
public List<B> Bs {get; protected set;}
}
public class B
{
public Guid Id {get; protected set;}
public C C {get; protected set;}
}
public record C{}
public record C1:C{}
PUBLIC record C2:C{}
public AClassTypeConfiguration : IEntityTypeConfiguration<A>
{
public void Configure(EntityTypeBuilder<A> builder)
{
builder.HasKey(p => p.Id);
builder.OwnsMany(p => p.Bs, p =>
{
p.HasKey(g => g.Id);
p.Property(g => g.Id).ValueGeneratedNever();
p.HasOne(g => g.C);
});
}
}
public CClassTypeConfiguration : IEntityTypeConfiguration<C>
{
public void Configure(EntityTypeBuilder<C> builder)
{
builder.HasNoKey();
builder.HasDiscriminator<int>("SubType")
.HasValue<C1>(1);
.HasValue<C2>(2);
}
}
公共A类
{
公共Guid Id{get;protected set;}
公共列表Bs{get;protected set;}
}
公共B级
{
公共Guid Id{get;protected set;}
公共C{get;受保护集;}
}
公共记录{}
公共记录C1:C{}
公共记录C2:C{}
因为类型C有子类,在Fluent API中,我将其配置为:
public class A
{
public Guid Id {get; protected set;}
public List<B> Bs {get; protected set;}
}
public class B
{
public Guid Id {get; protected set;}
public C C {get; protected set;}
}
public record C{}
public record C1:C{}
PUBLIC record C2:C{}
public AClassTypeConfiguration : IEntityTypeConfiguration<A>
{
public void Configure(EntityTypeBuilder<A> builder)
{
builder.HasKey(p => p.Id);
builder.OwnsMany(p => p.Bs, p =>
{
p.HasKey(g => g.Id);
p.Property(g => g.Id).ValueGeneratedNever();
p.HasOne(g => g.C);
});
}
}
public CClassTypeConfiguration : IEntityTypeConfiguration<C>
{
public void Configure(EntityTypeBuilder<C> builder)
{
builder.HasNoKey();
builder.HasDiscriminator<int>("SubType")
.HasValue<C1>(1);
.HasValue<C2>(2);
}
}
public AClassTypeConfiguration:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder)
{
HasKey(p=>p.Id);
builder.OwnsMany(p=>p.Bs,p=>
{
p、 HasKey(g=>g.Id);
p、 属性(g=>g.Id).ValueGeneratedNever();
p、 哈松(g=>g.C);
});
}
}
公共CClassTypeConfiguration:IEntitypeConfiguration
{
公共void配置(EntityTypeBuilder)
{
builder.HasNoKey();
builder.HasDiscriminator(“子类型”)
.HasValue(1);
.HasValue(2);
}
}
但当我调试代码时,它会抛出一个InvalidOperationException,并显示消息“无法确定由“C”类型的导航“B.C”表示的关系。请手动配置关系,或使用“[NotMapping]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.ignore”忽略此属性
那么如何在EF Core 5 Fluent API中配置具有继承关系的值对象呢?您可以将
B
、B1
、B2
定义为类型层次结构。每个都有一个[NotMapped]
属性,该属性分别返回C
、C1
、C2
记录。@Jeremylakman感谢您的评论,但这将破坏域模型的设计,这意味着技术实现反过来会影响业务模型的设计。我不认为没有密钥就可以在B和C之间设置FK。但是B有可能拥有一个C,用一个鉴别器<代码>新EntityTypeBuilder(p.OwnsOne(g=>g.C).OwnedEntityType.HasDiscriminator代码>。但我对EF核心对记录的支持一无所知。@JeremyLakeman嗨Jeremy,我从问题中了解到owned不支持继承(在可预见的将来不一定支持它)(我指的是你最初的建议。此外,record是一个新的语法糖,它只是一个特殊的类,efcore仍然使用原始逻辑来处理它。再次感谢你的帮助。