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