c# - Entity Framework TPC: Why does BaseEntity Id need to be of type Guid? -
i have been experiencing objectcontext inconsistent state exception:
the changes database committed successfully, error occurred while updating object context. objectcontext might in inconsistent state. inner exception message: acceptchanges cannot continue because object's key values conflict object in objectstatemanager. make sure key values unique before calling acceptchanges.
this seems happen when base entity (abstract since using tpc) has an
public int id { get; set;}
which configured primary key generated database:
// base entity modelbuilder.entity<baseentityobject>().haskey(t => t.id); modelbuilder.entity<baseentityobject>().property(t => t.id). hasdatabasegeneratedoption(databasegeneratedoption.identity);
and derived entities inheriting , trying use primary key.
when instantiate 2 different types of derived entries, add them dbcontext, try savechanges(), exception fired. however, when id field changed guid int:
public guid id { get; set;}
this exception no longer thrown.
can explain why happens when id property of type int?
is there workaround this? seems bit wasteful have every single derived entity have guid pk.
i think problem facing because configuring primary key , identity base entity supposed same derived entity because in general not storing baseentityobject in database.
you need below:
modelbuilder.entity<derivedentityobject1>().haskey(t => t.id); modelbuilder.entity<derivedentityobject1>().property(t => t.id). hasdatabasegeneratedoption(databasegeneratedoption.identity); modelbuilder.entity<derivedentityobject2>().haskey(t => t.id); modelbuilder.entity<derivedentityobject2>().property(t => t.id). hasdatabasegeneratedoption(databasegeneratedoption.identity);
update:
create base entity type configuration , inherit in entity configuration.
public class testcontext : dbcontext { public dbset<testentity1> testentities1 { get; set; } public dbset<testentity2> testentities2 { get; set; } protected override void onmodelcreating(dbmodelbuilder modelbuilder) { modelbuilder.configurations.add(new testentity1configuration()); modelbuilder.configurations.add(new testentity2configuration()); base.onmodelcreating(modelbuilder); } } public class baseentityconfiguration<t> : entitytypeconfiguration<t> t : baseentity { public baseentityconfiguration() { haskey(d => d.id).property(d => d.id).hasdatabasegeneratedoption(system.componentmodel.dataannotations.schema.databasegeneratedoption.identity); } } public class testentity1configuration : baseentityconfiguration<testentity1> { //your configuration here. } public class testentity2configuration : baseentityconfiguration<testentity2> { //your configuration here. }
smart way use data annotation below:
public class baseentity { [key] [databasegenerated(system.componentmodel.dataannotations.schema.databasegeneratedoption.identity)] public int id { get; set; } } public class testentity1 : baseentity { public string name { get; set; } } public class testentity2 : baseentity { public string name2 { get; set; } }
Comments
Post a Comment