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 performancereportentry
s not byperiodperformancereportentry
s? 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
basereportentry
class , move propertiesperformancereportentry
. makes no sense have base class 1 single other class derives from.remove
byperiodperformancereportentries
reportsbundle
,reportsbundle
be: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
.performancereportentrymap
should 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
byperiodperformancereportentrymap
entitytypeconfiguration<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.byperiodperformancereportentrymap
this: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