Getting schema information from an edmx file with POCO

by John Nye

04 Jun
2011

In this example I have two tables in my database, Customer and Company. Customer belongs to the dbo schema whereas Company belongs to the 'other' schema. By default the edmx file does not offer up information about the schema of the original tables however this is something that is stored in the underlying xml.

xml scheme

To retrieve this information we need to edit our tt template.

NOTE: I'd recommend getting tangible T4 Editor when working with .tt files as it provides syntax highlighting and intellisense which makes working with these file much easier.

At the top of our tt template (after the input file has been declared) we need to create a new store item collection that will grab the schema information using the code below.

StoreItemCollection sic;
loader.TryCreateStoreItemCollection(inputFile, out sic);
EntityContainer sicEntityContainer = sic.GetItems().FirstOrDefault();

Then from within the foreach (EntityType entity in ItemCollection.GetItems()...) loop you can get the current schema name with the following:

string schemaName = "Unknown";
if (sicEntityContainer != null)
{
    EntitySet eset = sicEntityContainer.GetEntitySetByName(code.Escape(entity), true);
    schemaName = eset.MetadataProperties["Schema"].Value.ToString();
}

Now we have the schema name we can do what we like with it. You might want to add a readonly property by adding the following just after the class is created.

public string Schema
{
    get { return "<#= schemaName #>"; }

}

With these small changes our auto generated classes now look like this:

Code comparison

Hope this helps

Comments 4

Fernando says: 2793 days ago

Nice... and what about with EF6??... "TryCreateStoreItemCollectio" doesn't work in EF6..

I think it might be done with the "MetadataWorkspace" method to retrieve the <EntityContainer> node, but didn't find a solution yet,.. can you help me? thanks

John says: 2782 days ago

Hi Fernando,

Unfortunately I haven't tested this approach on EF6 so can't confirm whether or not it is still appropriate. If you do find a solution, I'd love to hear it.

Regards John

Matt says: 2361 days ago

Kind of late to the party here, but I was able to get the schema in EF6 by parsing the raw XML of the edmx file to create mapping. I only did it for the functions, but this can be repurposed for the tables as well easily enough:

var xml = XElement.Load(textTransform.Host.ResolvePath(inputFile), LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); var schemaMap = xml .Elements() .First(x => x.Name.LocalName == "Runtime") .Elements() .First(x => x.Name.LocalName == "StorageModels") .Elements() .First() .Elements() .Where(x => x.Name.LocalName == "Function") .ToDictionary(x => x.Attribute("Name").Value, x => x.Attribute("Schema").Value);

Patrick says: 2353 days ago

Thanks @Matt. I ended up doing the same thing after trying several different ways to get the schema from the conceptual model FunctionImport without success. It was especially frustrating because the FunctionImport had a MetadataProperty with the name "Schema", but its value was null.

Leave a message...

18 Apr
2024