Wrapped System.IO.FileNotFoundException with Entity Framework POCO and Self-Tracking Entities T4 Templates
Visual Studio 2010 and .NET 4.0 were released on Monday! The Self-Tracking Entities template is included in the box, and the POCO Template we released some time ago in Visual Studio Gallery is compatible with the RTM version.
A few days ago we found a small issue in some of our code generation templates. It is really not a major problem with their functionality but rather a case of an unhelpful exception message being shown in Visual Studio when the source EDMX file is not found. So, I am blogging about it with the hope that people getting this exception will put the information in their favorite search engine and will find here what they need to know.
If you open any of our code generation templates you will see near the top a line that contains the name of the source EDMX file, i.e. something like this:
string inputFile = @"MyModel.edmx";
This line provides the source metadata that is used to generate the code for both the entity types and the derived ObjectContext. The string value is a relative path from the location of the TT file to the EDMX file, so if you change the location of either, you will normally have to open the TT file and edit the line to compensate for the change, for instance:
string inputFile = @"..\\Model\\MyModel.edmx";
If you make a typo or for some other reason the template cannot find the EDMX file, you will in general see a System.IO.FileNotFoundException in the Error List pane in Visual Studio:
Running transformation: System.IO.FileNotFoundException: Unable to locate file File name: 'c:\Project\WrongModelName.edmx' ...
Now, the exception message above is the version thrown by the “ADO.NET EntityObject Generator” (which is the default code generation template used by EF), and it is quite helpful actually, because it provides the file name that caused the error.
On the other side, if you are using the “ADO.NET POCO Entity Generator” or the “ADO.NET Self-Tracking Entity Generator”, the exception is going to be wrapped in a reflection exception and therefore you won’t directly get the incorrect file name:
Running transformation: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Unable to locate file ...
Something very similar happens when you add the template to your project incorrectly. Our code generation templates have been designed to be added through the “Add Code Generation Item…” Option in the Entity Data Model Designer:
When you do it this way, we automatically write the name of your EDMX file inside the TT file. But if you add the template to the project in some other way, for instance, using the standard “Add New Item” option in the Solution Explorer, the name of the EDMX file will not be written in the TT file, and instead a string replacement token will remain:
string inputFile = @"$edmxInputFile$";
When this happens, again, the exception message you get from the EntityObject generator is quite helpful:
Running transformation: Please overwrite the replacement token '$edmxInputFile$' with the actual name of the .edmx file you would like to generate from.
But unfortunately, for the POCO and the Self-Tracking Entities templates you will just get a wrapped System.IO.FileNotFoundException as in the examples above.
In any case, the solution is always the same: open the TT file, and replace the token manually with the name or relative path to the EDMX file. Alternatively, remove the template files from the project and add them again using “Add Code Generation Item…”.
I hope you will find this information helpful.