c# - Get TableName of Entity while using Fluent API -
i'm using fluent api change names of tables entities like:
public class testmap : entitytypeconfiguration<domain.test> { public testmap() { totable("test"); } } now later on in dbcontext want find table name type when inside metadataworkspace can't find type domain.test. able find table "tests" can't match unless hard code. question how can find typename inside metadataworkspace.
the code i'm using try , find type domain.test:
objectcontext octx = (context iobjectcontextadapter).objectcontext; ; var es = octx.metadataworkspace .getitems<entitycontainer>(dataspace.sspace) .selectmany(c => c.baseentitysets); edit, simplefied example of code people test:
using system; using system.collections.generic; using system.data.entity; using system.data.entity.core.mapping; using system.data.entity.core.metadata.edm; using system.data.entity.infrastructure; using system.data.entity.modelconfiguration; using system.data.entity.modelconfiguration.conventions; using system.linq; namespace test { class program { static void main(string[] args) { var db = new database(); db.set<test>().add(new test {name = "test"}); var amount = db.savechanges(); } public abstract class abstracttest { public int id { get; set; } } public class test : abstracttest { public string name { get; set; } } public class database : dbcontext { public database() : base("database") { this.configuration.proxycreationenabled = false; this.configuration.lazyloadingenabled = false; } protected override void onmodelcreating(dbmodelbuilder modelbuilder) { base.onmodelcreating(modelbuilder); // remove pluralized tables modelbuilder.conventions.remove<pluralizingtablenameconvention>(); modelbuilder.conventions.remove<pluralizingentitysetnameconvention>(); // add configurations within current assembly. modelbuilder.configurations.addfromassembly(typeof(database).assembly); } public override int savechanges() { foreach (dbentityentry ent in changetracker.entries()) { type entitytype = ent.entity.gettype(); var names = utility.gettablenames(entitytype, this); } return base.savechanges(); } } public class abstracttestmap : entitytypeconfiguration<abstracttest> { public abstracttestmap() { this.haskey(t => t.id); } } public class testmap : entitytypeconfiguration<test> { public testmap() { this.property(t => t.name) .hasmaxlength(200); totable("tests"); } } public static class utility { public static ienumerable<string> gettablenames<tentity>(dbcontext context) { return gettablenames(typeof(tentity), context); } public static ienumerable<string> gettablenames(type type, dbcontext context) { var metadata = ((iobjectcontextadapter)context).objectcontext.metadataworkspace; // part of model contains info actual clr types var objectitemcollection = ((objectitemcollection)metadata.getitemcollection(dataspace.ospace)); // entity type model maps clr type var entitytype = metadata .getitems<entitytype>(dataspace.ospace) .single(e => objectitemcollection.getclrtype(e) == type); // entity set uses entity type var entityset = metadata .getitems<entitycontainer>(dataspace.cspace) .single() .entitysets .single(s => s.elementtype.name == entitytype.name); // find mapping between conceptual , storage model entity set var mapping = metadata.getitems<entitycontainermapping>(dataspace.csspace) .single() .entitysetmappings .single(s => s.entityset == entityset); // find storage entity sets (tables) entity mapped var tables = mapping .entitytypemappings.single() .fragments; // return table name storage entity set return tables.select(f => (string)f.storeentityset.metadataproperties["table"].value ?? f.storeentityset.name); } } } }
working entity:
namespace yournamespace.domain{ public class test{ public int id { get; set; } public string name { get; set; } } } and map:
namespace yournamespace { public class testmap : entitytypeconfiguration<domain.test> { public testmap() { totable("test"); } } } and context:
namespace yournamespace { public class mycontext : dbcontext{ public dbset<test> tests { get; set; } protected override void onmodelcreating(dbmodelbuilder modelbuilder){ base.onmodelcreating(modelbuilder); modelbuilder.configurations .addfromassembly(assembly.getexecutingassembly()); } } } you can use method:
public static class utility { public static ienumerable<string> gettablenames<tentity>(this dbcontext context) { return gettablenames(typeof(tentity), context); } public static ienumerable<string> gettablenames(type type, dbcontext context) { var metadata = ((iobjectcontextadapter)context).objectcontext.metadataworkspace; // part of model contains info actual clr types var objectitemcollection = ((objectitemcollection)metadata.getitemcollection(dataspace.ospace)); // entity type model maps clr type var entitytype = metadata .getitems<entitytype>(dataspace.ospace) .single(e => objectitemcollection.getclrtype(e) == type); // entity set uses entity type var entityset = metadata .getitems<entitycontainer>(dataspace.cspace) .single() .entitysets .single(s => s.elementtype.name == entitytype.name); // find mapping between conceptual , storage model entity set var mapping = metadata.getitems<entitycontainermapping>(dataspace.csspace) .single() .entitysetmappings .single(s => s.entityset == entityset); // find storage entity sets (tables) entity mapped var tables = mapping .entitytypemappings.single() .fragments; // return table name storage entity set return tables.select(f => (string)f.storeentityset.metadataproperties["table"].value ?? f.storeentityset.name); } } it return list of table names. single table entity - case -, use tablenames.firstordefault(t=> !string.isnullorwhitespace(t)). also, can use utility method or extension method:
class program { static void main(string[] args) { // getting list: using (var ctx = new mycontext()){ var tablenames = ctx.gettablenames<test>(); foreach (var tablename in tablenames) console.writeline(tablename); console.readline(); } // getting single table-name - case - using (var ctx = new mycontext()){ var tablenames = ctx.gettablenames<test>(); var tablename = tablenames.firstordefault(t=> !string.isnullorwhitespace(t)) console.writeline(tablename); console.readline(); } } } see source article here.
update:
based on updated question: have hierarchymapping here; need change our gettablenames method support inheritance:
public static class utility { public static ienumerable<string> gettablenames<tentity>(this dbcontext context) { return gettablenames(typeof(tentity), context); } public static ienumerable<string> gettablenames(type type, dbcontext context) { var metadata = ((iobjectcontextadapter)context).objectcontext.metadataworkspace; // part of model contains info actual clr types var objectitemcollection = ((objectitemcollection)metadata.getitemcollection(dataspace.ospace)); // entity type model maps clr type var entitytype = metadata .getitems<entitytype>(dataspace.ospace) .single(e => objectitemcollection.getclrtype(e) == type); // entity set uses entity type var entitysettop = metadata .getitems<entitycontainer>(dataspace.cspace).selectmany(s => s.entitysets); //.single() //.baseentitysets; var entityset = entitysettop .singleordefault(s => s.elementtype.name == entitytype.name); entityset entityset2 = null; foreach (var s in entitysettop) { if (s.elementtype.name == entitytype.name) { entityset2 = s; break; } var temp = entitytype.basetype; while (temp != null) { if (s.elementtype.name == temp.name) { entityset2 = s; break; } temp = temp.basetype; } if (entityset2 != null) break; } entityset = entityset2; // find mapping between conceptual , storage model entity set var mapping = metadata.getitems<entitycontainermapping>(dataspace.csspace) .single() .entitysetmappings .single(s => s.entityset == entityset); // find storage entity sets (tables) entity mapped var tables = mapping .entitytypemappings.where(f => { if (f.ishierarchymapping) { return f.entitytypes.any(e => e.name == entitytype.name); } return f.entitytype.name == entitytype.name; }).selectmany(t => t.fragments); //.single() //.fragments; // return table name storage entity set return tables.select(f => (string)f.storeentityset.metadataproperties["table"].value ?? f.storeentityset.name); } }
Comments
Post a Comment