Question

So I've upgraded an existing MVC4 project to .NET4.5 and EF5. I've run the project and everything works properly. Then I tried to run my custom scaffolder, and it gave me no love.

Please forgive me if this is a simple mistake, but our templates were written by someone who left the company. I've done my best to understand how these work and try and debug it. But after an afternoon of banging my head on my desk, I've hit a dead end...

The error message I receive is -

Add-ProjectItemViaTemplate : <Path To>\CodeTemplates\Scaffolders\sfRepository\Repository.cs.t4(0,0) : error : Running transformation:  System.InvalidOperationException: Sequence contains no elements    at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)    at Microsoft.VisualStudio.TextTemplatingF690EB8002D6F86A4E8AE00CFB7DAA03C9EB647292D7F28842F3EE3F3550C224E18FB3EC09900009A804CDFD9776A0AFB2AE2497DE3D77DEF417124AC7DE860B.Genera tedTextTransformation.TransformText() At <Path To>\CodeTemplates\Scaffolders\sfRepository\sfRepository.ps1:39 char:1
+ Add-ProjectItemViaTemplate $outputPath -Template Repository -Model @{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-ProjectItemViaTemplate], Exception
    + FullyQualifiedErrorId : T4Scaffolding.Cmdlets.AddProjectItemViaTemplateCmdlet

So I looked at my T4 template itself. By process of elimination, I have found the error to happen on this line -

var entity = ItemCollection.GetItems<EntityType>().Where(e => e.Name == Model.EntityName).First();

Here's a full copy of the template to that point -

<#@ template language="C#" HostSpecific="True"  inherits="DynamicTransform" #>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ assembly name="System.Data.Entity" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="EnvDTE" #>
<#@ Output Extension="cs" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="EnvDTE" #>
<#@ assembly name="System.ComponentModel.DataAnnotations" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="System.Data.Linq" #>
<#@ import namespace="System" #>
<#@ import namespace="System.ComponentModel.DataAnnotations" #>
<#@ import namespace="System.Data.Linq.Mapping" #>
<#@ import namespace="System.Data.Objects.DataClasses" #>
<#@ import namespace="System.Reflection" #>
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using Omu.ValueInjecter;
<# foreach(var ns in new[] { Model.ModelTypeNamespace, Model.DbContextNamespace }.Where(x => !string.IsNullOrEmpty(x) && (x != Model.RepositoryNamespace)).Distinct()) { #>
using <#= ns #>;
<# } #>
using <#=Model.Project#>.DataObjects;

namespace <#=Model.Project#>.Models
{ 
<# 
    var modelType = (CodeType)Model.ModelType; 
    var modelName = modelType.Name; 
    var modelNamePlural = Model.ModelTypePluralized; 
    var primaryKeyProperty = modelType.VisibleMembers().OfType<CodeProperty>().Single(x => x.Name == Model.PrimaryKey);

    CodeGenerationTools code = new CodeGenerationTools(this);
    MetadataLoader loader = new MetadataLoader(this);
    CodeRegion region = new CodeRegion(this, 1);
    MetadataTools ef = new MetadataTools(this);

    // create our item collection from the specified edmx
    EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(Model.InputFileName);

    // find our entity from the pool
    var entity = ItemCollection.GetItems<EntityType>().Where(e => e.Name == Model.EntityName).First();

I tried taking the where out, and just pulling the first item. There are still no items in the collection.

Best I can tell, the MetadataLoader in EF.Utility.CS.ttinclude isn't able to read my EF5 edmx for some reason.

I noticed that my local copy of EF.Utility.CS.ttinclude wasn't as recent as the one under "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes" so I tried copying that to my local project. Unfortunately there was no change.

I also verified that Model.InputFileName is holding the correct path to the edmx file.

So the question is... why? Is there something else I need to do to update my scaffolders for EF5 and .NET4.5? I haven't seen any common issues posted elsewhere about this...

Was it helpful?

Solution

On day two of this adventure I began converting EF.Utility.CS.ttinclude into a C# console app to see if I couldn't glean a better error message.

I noticed that the constants at the bottom of the file didn't include the newer EF5 namespaces.

I compared my copy with the one under "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes" and sure enough, mine was out of date.

During my debugging, I know I updated this (as I mentioned above). Either I copied it to the wrong folder, or I'm losing my mind. It could be either at this point.

Either way, the solution was simply to update my local copy of EF.Utility.CS.ttinclude with the one under "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes" and it then works perfectly.

Thanks to everyone who took the time to read my question!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top