You have to use a T4 template to do this (
http://www.ideablade.com/forum/forum_posts.asp?TID=1721&PID=6755#6755
).
Since I wrote that sample on switching parents (where I used the EDMX Summary attribute on the entity to specify the parent to use), I've changed to just make a call to another T4 template that takes the Entity name and looks up the parent to use.
Create a new T4 file, in this example, it's called "GetEntityParent.tt" and add it to your solution. After adding it, remove the Custom Tool name from the file properties in the solution explorer since we don't need this t4 to actually do anything. It's just an "include" file. Any entity that you don't want to switch will return an empty string (you could also just default it to whatever your common injected base type is) and the main routine will not change its parent. Obviously you could use an XML file to hold these relationships as well. To me, putting them in a code file is just as easy and (in our case) is checked into source control along with the models.
<#@ template language="C#" debug="true" hostSpecific="true" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Data.Entity.dll" #>
<#@ Assembly Name="Microsoft.VisualStudio.TextTemplating.10.0" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Data.Entity" #>
<#+
/// <summary>
/// Code Generation Function to get the parent entity for inheritence in the models
/// </summary>
public class GetEntityParentTemplate
{
public string GetEntityParent(string childEntity)
{
if (childEntity == "Table1")
{
return "BaseEntity";
}
if (childEntity == "Table2")
{
return "AuditEntity";
}
return string.Empty;
}
}
#>
Change the other T4 (the one that is <modelname>.edmx.tt) with these bolded changes:
<#@ template language="C#" debug="true" hostSpecific="true" #>
<#@ output extension=".ReadMe" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="Microsoft.VisualStudio.TextTemplating.10.0" #>
<#@ Assembly Name="IdeaBlade.Core" #>
<#@ Assembly Name="IdeaBlade.VisualStudio.DTE.dll" #>
<#@ Assembly Name="IdeaBlade.VisualStudio.OM.CodeGenerator.dll" #>
<#@ Assembly Name="IdeaBlade.EntityModel.Edm.Metadata.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="IdeaBlade.VisualStudio.DTE" #>
<#@ import namespace="IdeaBlade.VisualStudio.OM.CodeGenerator" #>
<#@ import namespace="IdeaBlade.EntityModel.Edm.Metadata" #>
<#@ include file="GetEntityParent.tt" #>
<#
// Model1.edmx <--- This is needed so that "Transform Related Text Templates On Save" works correctly.
var template = new MyTestTemplate(this);
template.Generate();
#>
<#+
public class MyTestTemplate : DomainModelTemplate {
public MyTestTemplate(Microsoft.VisualStudio.TextTemplating.TextTransformation textTransformation)
:base(textTransformation) {}
GetEntityParentTemplate _getEntityParentTemplate = new GetEntityParentTemplate();
protected override ClassDef GetEntityClassDef(EntityOrComplexTypeWrapper wrapper)
{
var _parentEntity = _getEntityParentTemplate.GetEntityParent (wrapper.Name);
if (_parentEntity != null && _parentEntity != String.Empty)
{
// generate the current ClassDef from the passed argument
ClassDef _classDef;
_classDef = base.GetEntityClassDef(wrapper);
// create a new class def instance as we're overridding it with a different base type
// and ClassDef.BaseTypeName has a private Setter so we use the ClassDef public
// constructor that takes Name, BaseTypeName and AccessType and then set the other properties
ClassDef _newClassDef = new ClassDef (_classDef.Name, _parentEntity, _classDef.AccessType);
// setup the remaining properties
_newClassDef.SetAbstract (_classDef.IsAbstract);
_newClassDef.SetNew (_classDef.IsNew);
_newClassDef.SetPartial (_classDef.IsPartial);
_newClassDef.SetStatic (_classDef.IsStatic);
// since we're overriding the base type to be a class, I'm setting this to false
// as I know it won't be an interface
_newClassDef.BaseTypeIsInterface = false;
// write a comment that we generated something different (useful for debugging as well)
WriteComment("");
WriteComment("Changed BaseTypeName to be: " + _newClassDef.BaseTypeName);
WriteComment("");
// return the new ClassDef
return (_newClassDef);
}
// DEFAULT
// just generate and return the normal ClassDef so all entities that just inherit directly
// from the base injected type remain the same
return (base.GetEntityClassDef(wrapper));
}
}
#>