I upgraded to Visual Studio 2012 and consequently upgraded to version 4.5 of the .NET framework. It turns out, this made our T4 templates very unhappy.
See, we use T4 templates for generating our Entity Framework(EF) models. A bunch of very fancy template coding that automagically creates our edmx and other code files from a reference database.
This worked very well in .NET 4.0, but simply upgrading to .NET 4.5 made it throw all sorts of fun errors.
The root cause turned out to be it was generating EF3 schema data which completely hosed the template code which was looking for EF2 schemas. Not to mention, I tried converting the template processing code to use the new schemas and then realized that since we target .NET 4.0, that we couldn’t compile after the templates worked.
So, I was stuck in a catch 22. Fix the templates, and can’t build the assembly, or only build the templates on a machine with .NET 4.0 and VS 2010. Both options suck.
Well, I reached out into the forums and got a little advice at least on targeting the right framework.
I changed the headers to target 4.0. That turned out to be Step 1.
<#@ template debug=”true” hostspecific=”false” language=”C#v4.0″ #>
<#@ output extension=”.edmx” #>
<#@ Assembly Name=”System.Core, Version=188.8.131.52, Culture=neutral” #>
<#@ Assembly Name=”System.Data, Version=184.108.40.206, Culture=neutral” #>
<#@ Assembly Name=”System.Data.Entity, Version=220.127.116.11, Culture=neutral” #>
<#@ Assembly Name=”System.Data.Entity.Design, Version=18.104.22.168, Culture=neutral” #>
<#@ Assembly Name=”System.Xml, Version=22.214.171.124, Culture=neutral” #>
<#@ Assembly Name=”System.Xml.Linq, Version=126.96.36.199, Culture=neutral” #>
Now, step 2. I discovered through hours of staring at code and hoping for hope to find an overload, setting,property or something to say….Damn it, I wan’t EF 2 code. Yeah, you would think running in 4.0 framework mode would do that for me, right? Nothing can be simple.
I finally found it. The overloads I needed.
EntityContainer entityContainer = this.storeItems.GetItems<EntityContainer>(); this.modelGenerator = new EntityModelSchemaGenerator(entityContainer, ModelNamespace, this.entityContainerName); this.modelGenerator.GenerateForeignKeyProperties = true; this.modelGenerator.PluralizationService = this.pluralizationService; this.modelGenerator.GenerateMetadata(EntityFrameworkVersions.Version2);
Generate MetaData has a Version overload.
So does the schema generator.
var generator = new EntityStoreSchemaGenerator(this.provider, this.connectionString, ModelNamespace + "." + StoreNamespace); IList<EdmSchemaError> errors = generator.GenerateStoreMetadata(this.filters,EntityFrameworkVersions.Version2);
So, now we have the fix. All is well in the world. Only lost a day or two of headbanging my screen and yelling at how much T4 is an undocumented piece of crap. Well, it least I have a stronger understanding of it now.
Hopefully this saves you some headache, since not one damn google search result explained this.