Consider improving model validation for when the derived type only has navigations and no discriminator
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
NET8. I will try to describe the issue as briefly as possible.
1) Nuget package **EntityConfig** contains _model-DB_ mappings;
2) Nuget package **Base** contains entity `TenantInner` and consumes **EntityConfig**: entity `TenantInner` is bound to table `TENANT`;
3) Solution **MySolution** consumes packages **EntityConfig** and **Base** and contains entity `Tenant` which inherits `TenantInner`. `Tenant` only contains navigation properties and naturally references the same table - `TENANT`.
The reason why I splitted `TenantInner` and `Tenant`: `TenantInner` is used in many solutions. `Tenant` contains several navigation properties - we do not want to pull them all into **Base**, since they are needed in **MySolution** only.
Problem: I cannot make this structure work, getting either "**A key cannot be configured on 'Tenant' because it is a derived type**" or "**ORA-00904: "C1"."DISCRIMINATOR": invalid identifier**" (this one happens when trying to construct EF query joining `DbSet` property in _DbContext_) exceptions, depending on the way I've tried to resolve the issue.
My latest setup (I don't think `TenantInner` structure is relevant here, so skipping):
============ EntityConfig Nuget package ===========================================
```
public class TenantEntityConfig : EntityConfigBase where TBase : TenantEntity
{
public TenantEntityConfig(Action> builder = null)
: base(builder)
{ }
public override void Configure(EntityTypeBuilder builder)
{
builder.ToTable("TENANT");
builder.HasKey(x => x.Id);
builder.Property(x => x.Id)
.HasColumnName("ID").IsRequired()
.ValueGeneratedNever();
builder.Property(x => x.ShortName)
.HasColumnName("NAME");
...
builder.Property(x => x.CompanyId)
.HasColumnName("COMPANY_ID").IsRequired();
...
base.Configure(builder);
}
}
public class TenantEntityConfig : TenantEntityConfig
{ }
```
============ MySolution ===========================================
```
public class Tenant : TenantInner
{
public Company Company { get; set; }
...
}
builder.ApplyConfiguration(new TenantEntityConfig());
builder.Entity(builder =>
{
builder.HasBaseType();
builder.HasOne(x => x.Company)
.WithMany()
.HasPrincipalKey(x => x.Id)
.HasForeignKey(x => x.CompanyId);
...
});
```
I don't understand why it should not work: as I see it, when `DbSet` is referenced - the EF should construct the query using `TENANT` table and its navigation properties tables (if included - `COMPANY` etc.). If `DbSet` is referenced (in **Base** package) - the same `TENANT` table should be used. However, I don't know how to let EF know that "discriminator" is not relevant here.
Contributor guide
Assessment
This issue has not been assessed yet.