views:

445

answers:

2

I am in the process of build a script for a fairly big project. One of the projects require an Entity Framework Model to be compiled into a library. Due to the way the build server works, all builds are hand crafted to manage the various deployment scenarios without affecting the developers and the project files.

Is there anyway to generate the EF Model using an MSBuild task without using the project file generated by Visual Studio? Currently the actual assembly compiles using a CSC task, however the actual deployed application fails because the EF Model is not included in the compiled assembly.

Any pointers into which Targets or Build Tasks can be used to generate the model and create the required resources to embed in the assembly?

Please Note

The project compiles fine in Visual Studio, however using the project file on the build server is not an option, as there is various changes that needs to be made to the project at deployment time, and this is controlled through a custom build script outside of the development teams control. This has worked succesfully for a few projects, however the EF Model is causing some headaches in this specific scenario.

Update

The current solution is not ideal but works. The Project file has been modified to copy the EF Model resources to a folder in the project on a new release build, which is then checked into source control. When the build script runs on the server the EF models are embedded into the assembly. This seems to be a workable workaround for the moment.

+1  A: 

Yes, there is a command-line utility called EdmGen which can do this. Use EdmGen /? for possible switches.

Craig Stuntz
+1  A: 

I actually dealt with this today since my project's source tree isn't properly setup to run the Entity Framework's build task which generates and embeds the resources in the output dll.

I investigated the following options:

Using the EntityDeploy msbuild task

If you open your .csproj file in notepad you should see a bit of XML like

 <EntityDeploy Include="MyEntities.edmx">
  <Generator>EntityModelCodeGenerator</Generator>
  <LastGenOutput>MyEntities.Designer.cs</LastGenOutput>
 </EntityDeploy>

This is the msbuild task that uses Microsoft.Data.Entities.Build.targets and Microsoft.Data.Entities.Build.dll to read the edmx file, generate the ssdl, csdl, and msl files and then embed them in the target dll. (These files can be found in C:\Windows\Microsoft.NET\Framework\v3.5).

Using EdmGen

As Craig pointed out, you might be able to use EdmGen.exe which ships with the framework. I gave that a go but I had done a bit of customization to the data in my edmx file and EdmGen.exe seems to really want to do the initial generation from the original database.

Using EdmGen2

EdmGen2.exe is an open-source project that does a bit more than EdmGen. I ended up using it to generate the ssdl, csdl, and msl files. You can just point it at your edmx file and it will generate the necessary ssdl, csdl, and msl files. I then included these alongside my dll and modified the connection string from

connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|res://*/MyEntities.msl;

to

connectionString="metadata=./MyEntities.csdl|./MyEntities.ssdl|./MyEntities.msl;

Note I'm telling the Entity framework that these files are in the same directory as my dll, not embedded as resources.

All three of these, the build task, EdmGen, and EdmGen2 are thin wrappers that call System.Data.Entity.dll for all of the hard stuff. As a last resort you could peek at the build task dll in reflector and see what it's doing.

Hope this helps.

nick