entity framework - Multiple level of inheritance in EF Code First Configuration -
i have abstract base class few entities i'm defining. 1 of derived entities non-abstract base class entity.
following code:
public abstract class basereportentry { public int reportentryid { get; set;} public int reportbundleid { get; set; } //fk public virtual reportbundle reportbunde { get; set; } } //a few different simple pocos 1 public performancereportentry : basereportentry { public int performanceabsolute { get; set; } public double performancerelative { get; set; } } //and 1 second level of inheritance public byperiodperformancereportentry : performancereportentry { public string period { get; set; } } i'm using base entitytypeconfiguration:
public class basereportentrymap<treportentry> : entitytypeconfiguration<treportentry> treportentry : basereportentry { public basereportentrymap() { this.haskey(e => e.reportentryid); this.hasrequired(e => e.reportsbundle) .withmany() .hasforeignkey(e => e.reportsbundleid); } } presumably works fine one-level of inheritance throw following error 1 case has second level:
the foreign key component 'reportsbundleid' not declared property on type 'byperiodperformancereportentry' public class byperiodperformancereportentrymap : basereportentrymap<byperiodperformancereportentry> { public byperiodperformancereportentrymap () : base() { this.property(e => e.period).isrequired(); this.map(m => { m.mapinheritedproperties(); m.totable("byperiodperformancereportentries"); }); } } here's reportbundle class if needed
public class reportsbundle { public int reportsbundleid { get; set; } public virtual icollection<performancereportentry> performancereportentries{ get; set; } public virtual icollection<byperiodperformancereportentry> byperiodperformancereportentries{ get; set; } }
the problem not second level of inheritance performancereportentry (the base of byperiodperformancereportentry) entity while basereportentry (the base of performancereportentry) not.
your mapping work if performancereportentry not entity - i.e. mapping not added model builder configuration , have no dbset type , not occur in navigation collection in reportsbundle.
deriving configuration basereportentrymap<byperiodperformancereportentry> not possible in case - , not necessary because mapping base properties happened basereportentrymap<performancereportentry>. therefore can use
public class byperiodperformancereportentrymap : entitytypeconfiguration<byperiodperformancereportentry> but have doubt resulting model expect it. don't know performancereportentries , byperiodperformancereportentries collections in reportsbundle supposed express. expect byperiodperformancereportentries collection filtered subtype? expect performancereportentries contains reportsentries performancereportentrys not byperiodperformancereportentrys? expect performancereportentries contains entries including byperiodperformancereportentries?
anyway, basereportentry.reportbundle navigation property mapped in performancereportentry (not in byperiodperformancereportentry). means inverse navigation property in class reportsbundle must refer performancereportentry performancereportentries navigation collection. byperiodperformancereportentries introduce second one-to-many relationship between reportsbundle , byperiodperformancereportentry (without navigation property in byperiodperformancereportentry). inverse navigation property of byperiodperformancereportentries not basereportentry.reportbundle.
my feeling should not have reportsbundle.byperiodperformancereportentries collection, not sure want achieve exactly.
edit
refering comment have these 2 report types mapping way complicated in opinion. following:
remove
basereportentryclass , move propertiesperformancereportentry. makes no sense have base class 1 single other class derives from.remove
byperiodperformancereportentriesreportsbundle,reportsbundlebe:public class reportsbundle { public int reportsbundleid { get; set; } public virtual icollection<performancereportentry> performancereportentries { get; set; } }remove
basereportentrymap, move mappingperformancereportentrymap. derive mapentitytypeconfiguration<performancereportentry>.correct mapping. wrong because don't specify inverse navigation property in
withmany.performancereportentrymapshould this:public class performancereportentrymap : entitytypeconfiguration<performancereportentry> { public performancereportentrymap() { this.haskey(e => e.reportentryid); this.hasrequired(e => e.reportsbundle) .withmany(b => b.performancereportentries) .hasforeignkey(e => e.reportsbundleid); } }derive
byperiodperformancereportentrymapentitytypeconfiguration<byperiodperformancereportentry>, specify mappings properties declared inbyperiodperformancereportentry, not again base properties. happened inperformancereportentrymap. don't need , can't specify again because cause exception had.use table-per-hierarchy (tph) inheritance instead of table-per-concrete-type (tpc), if have few properties declared in
byperiodperformancereportentry. tpc more difficult use because has problems database-generated identities , polymorphic associations (which have in relationship betweenperformancereportentry,reportsbundle). the problems explained in more details here. tph instead offers best performance.byperiodperformancereportentrymapthis:public class byperiodperformancereportentrymap : entitytypeconfiguration<byperiodperformancereportentry> { public byperiodperformancereportentrymap() { this.property(e => e.period).isrequired(); } }no explicit configuration tph necessary because default inheritance mapping.
Comments
Post a Comment