Multiple Inheritance Using Entity Framework TPC

I tried to map some classes using Entity Framework in TPC style and got the following error:

Error: Type "A" cannot be displayed as defined, because it displays inherited properties from types that use object separation or other forms of inheritance. Either choose another strategy inheritance so that you don’t display inherited properties or change all types in a hierarchy to display inherited properties and not use separation.

This error occurs when I use the following classes:

public abstract class BaseEntityTest public abstract class BaseEntityTest2 : BaseEntityTest public abstract class BaseEntityTest3 : BaseEntityTest2 public class A: BaseEntityTest3 // this class is the only one with a table in the db 

In the OnModelCreating method, I added the following code to get the TPC mapping

 modelBuilder.Entity<A>().Map(m => { m.MapInheritedProperties(); m.ToTable("A"); }); 

When I exclude BaseEntityTest2 from the structure (so that A inherits only from BaseEntityTest instead of BaseEntityTest2), the error disappears. Does this mean that it is impossible to create this mapping, or am I just missing something?

EDIT:

Class Properties:

 public abstract class BaseEntityTest { [Key] public Guid Id { get; set; } public String Info { get; set; } [Required] public DateTime CreationDate { get; set; } [Required] public String CreationUser { get; set; } [Required] public DateTime ModificationDate { get; set; } [Required] public String ModificationUser { get; set; } [ConcurrencyCheck] [Required] public int LockVersion { get; internal set; } } public abstract class BaseEntityTest2 : BaseEntityTest { [Required] public string Name { get; set; } public string Description { get; set; } } public abstract class BaseEntityTest3: BaseEntityTest2 { [Required] public DateTime FromDate { get; set; } public DateTime ThruDate { get; set; } } public class A: BaseEntityTest3{ public String Test { get; set; } } 
+4
source share
2 answers

The error occurs for EF 4.3.1 and earlier, but not for EF 4.4 and EF 5.0. (EF 4.4 is actually EF 5.0, but with .NET 4.0 as the target platform.)

BUT: An error occurs only if you use abstract classes as objects in your model, this means

  • you either have a DbSet for them in your context e.g.

     public DbSet<BaseEntityTestX> BaseEntityTestXs { get; set; } 
  • or you have a Fluent mapping for BaseEntityTestX , some modelBuilder.Entity<BaseEntityTestX>()... stuff

  • or you use one of BaseEntityTestX as a navigation property in another (specific) object type

Do you need any of this?

Having a DbSet<BaseEntityTestX> in your context only makes sense if you really want to query one of the abstract objects, for example:

 List<BaseEntityTest> list = context.BaseEntityTests .Where(b => b.Info == "abc").ToList(); 

The result is, of course, a list of specific objects that inherit from BaseEntityTest , but it can be a combination of different types, such as some A and some B s. Do you need such requests? Or do you want to request only some of the specific objects:

 List<A> list = context.As .Where(b => b.Info == "abc").ToList(); 

In the latter case, you do not need DbSet for abstract base classes, and you do not need inheritance matching. You can simply remove the DbSet<BaseEntityTestX> from your context class and remove the TPC mapping, and your error will disappear.

The last point - the presence of a navigation property for one of the abstract objects in another object - does not make sense when comparing TPC. It simply is not suitable for a relational database, because when comparing TPC there is no table for an abstract object, therefore there is no goal to which the relation of foreign keys could relate to a table of a particular class that has the navigation property.

The error will also disappear if you increase the mapping of TPC to base classes:

 modelBuilder.Entity<BaseEntityTestX>().Map(m => { m.MapInheritedProperties(); m.ToTable("BaseEntityTestX"); }); 

But he will create tables for those abstract objects that do not seem to make sense to me.

+6
source

in EF6.0 when it happened when

EntityTypeConfiguration '<' YourBaseClass '>'

ALL your derived class with

  this.Map<DerivedClass1>(m => { m.MapInheritedProperties(); m.ToTable(".."); }); 

if only one silenced class in the assembly is not configured so you get this exception

+2
source

Source: https://habr.com/ru/post/970194/


All Articles