C
C#2y ago
nlohim

❔ EF inheritance, selecting from multiple children

So I have this entity ProcessSpec, and 2 classes inherit from it. I'd like to be able to select a list of all ProcessSpecs, is this possible with EF? I (think I) know inheritance can be done in 2 ways, 1) with a discriminator column. 2) with the abstract parent and 2 separate database tables for the children. Is what I want to achieve possible? I currently have it set-up with a discriminator and when I try to select from all the children I get this error which I cannot find much info about.
16 Replies
Anton
Anton2y ago
show the code
nlohim
nlohimOP2y ago
For which?
Anton
Anton2y ago
the entities and the configuration
nlohim
nlohimOP2y ago
ProcessSpec parent:
public class ProcessSpec : SpecBase
{
public ProcessSpec()
{
ProcessSpecDosimeterLoadings = new List<ProcessSpecDosimeterLoading>();
DosimeterLoads = new List<DosimeterLoad>();
}

[Key]
public int ProcessSpecId { get; set; }

[MaxLength(255)]
public string ProcessSpecName { get; set; }

public int TreatmentSystemId { get; set; }

/// <summary>
/// Describes this process spec
/// </summary>
[MaxLength(255)]
public string Description { get; set; }
}

inheritance 1:
public class ProcessSpecGamma : ProcessSpec
{
/// <summary>
/// Refers to the density (in g/cm³) of the minimum density to be used in the process.
/// </summary>
[Column(TypeName = "decimal(18,3)")]
public decimal? MinDensity { get; set; }

/// <summary>
/// Refers to the density (in g/cm³) of the maximum density to be used in the process.
/// </summary>
[Column(TypeName = "decimal(18,3)")]
public decimal? MaxDensity { get; set; }
}
ProcessSpec parent:
public class ProcessSpec : SpecBase
{
public ProcessSpec()
{
ProcessSpecDosimeterLoadings = new List<ProcessSpecDosimeterLoading>();
DosimeterLoads = new List<DosimeterLoad>();
}

[Key]
public int ProcessSpecId { get; set; }

[MaxLength(255)]
public string ProcessSpecName { get; set; }

public int TreatmentSystemId { get; set; }

/// <summary>
/// Describes this process spec
/// </summary>
[MaxLength(255)]
public string Description { get; set; }
}

inheritance 1:
public class ProcessSpecGamma : ProcessSpec
{
/// <summary>
/// Refers to the density (in g/cm³) of the minimum density to be used in the process.
/// </summary>
[Column(TypeName = "decimal(18,3)")]
public decimal? MinDensity { get; set; }

/// <summary>
/// Refers to the density (in g/cm³) of the maximum density to be used in the process.
/// </summary>
[Column(TypeName = "decimal(18,3)")]
public decimal? MaxDensity { get; set; }
}
inheritance 2:
public class ProcessSpecBeam : ProcessSpec
{
/// <summary>
///
/// </summary>
public ProcessSpecMevex()
{
}

/// <summary>
/// Specifies the type of ProcessSpec, including the form configuration.
/// </summary>
public int? ProcessSpecTypeId { get; set; }

/// <summary>
/// Specifies which label option will be used by this Process Spec.
/// </summary>
public int? LabelOptionId { get; set; }

/// <summary>
/// Specifies the orientation of the barcode on the label.
///
/// Note: Perhaps this could be added to Shipper or LoadingPattern?
/// </summary>
public int? BarcodeOrientationId { get; set; }

/// <summary>
/// Specifies whether the carrier dimensions will be used for the process.
/// </summary>
public bool UseCarrierAssociations { get; set; }
}
inheritance 2:
public class ProcessSpecBeam : ProcessSpec
{
/// <summary>
///
/// </summary>
public ProcessSpecMevex()
{
}

/// <summary>
/// Specifies the type of ProcessSpec, including the form configuration.
/// </summary>
public int? ProcessSpecTypeId { get; set; }

/// <summary>
/// Specifies which label option will be used by this Process Spec.
/// </summary>
public int? LabelOptionId { get; set; }

/// <summary>
/// Specifies the orientation of the barcode on the label.
///
/// Note: Perhaps this could be added to Shipper or LoadingPattern?
/// </summary>
public int? BarcodeOrientationId { get; set; }

/// <summary>
/// Specifies whether the carrier dimensions will be used for the process.
/// </summary>
public bool UseCarrierAssociations { get; set; }
}
BaseDbContext:
public class BaseSpecificationContext : BaseContext
{
public BaseSpecificationContext(IConfiguration configuration) : base(configuration)
{
}

public BaseSpecificationContext()
{
}

public DbSet<ProcessSpec> ProcessSpec { get; set; }
}

DbContext 2:
public class SpecificationContext_19 : BaseSpecificationContext
{
public SpecificationContext_19(IConfiguration configuration) : base(configuration)
{
}

public SpecificationContext_19()
{
}

public new DbSet<ProcessSpecMevex> ProcessSpec { get; set; }
}
BaseDbContext:
public class BaseSpecificationContext : BaseContext
{
public BaseSpecificationContext(IConfiguration configuration) : base(configuration)
{
}

public BaseSpecificationContext()
{
}

public DbSet<ProcessSpec> ProcessSpec { get; set; }
}

DbContext 2:
public class SpecificationContext_19 : BaseSpecificationContext
{
public SpecificationContext_19(IConfiguration configuration) : base(configuration)
{
}

public SpecificationContext_19()
{
}

public new DbSet<ProcessSpecMevex> ProcessSpec { get; set; }
}
Anything else?
Anton
Anton2y ago
wait what two contexts?
nlohim
nlohimOP2y ago
We have many contexts, 1 for each feature
Anton
Anton2y ago
I don't even know how inheriting a base context multiple times works, so sorry, I can't help you also if you're not planning to instantiate the base entity, make ot abstract
nlohim
nlohimOP2y ago
I may be wrong, but I don't think it would matter much. I can try to declare the inheritance classes' DbSets in the base context, I believe the result will be the same
Anton
Anton2y ago
same with all base classes
nlohim
nlohimOP2y ago
If you make the base entity abstract, EF will create a separate table for each child instead of 1 table
Anton
Anton2y ago
inheriting db context is just something I would never even consider
nlohim
nlohimOP2y ago
I wasn't part of the decision making for this project 😦 It is what it is now
Anton
Anton2y ago
not necessarily you can configure it to use a single table read the document on inheritance in ef
nlohim
nlohimOP2y ago
Thank you ❤️
Anton
Anton2y ago
np
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server