简体   繁体   中英

How to embed EDMX in a Code First assembly?

We're using Code First in EF6.1 - our model is over 300+ tables now and startup time is ridiculous. We've tried pregenerating views already but it didn't help much, it's the model compilation in the Code First pipeline that takes most of the time.

We're going to try using the Database / Model First approach for initializing the context by using an entity connection string with metadata links to CSDL, SSDL and MDL files, instead of a direct SQL connection. This would be our ideal process:

  1. After the project containing the Code First model is compiled, a post-build task runs that generates an EDMX file from our DbContext, splits it into component CSDL, SSDL and MDL files, and embeds these files in the assembly as resources
  2. When we create a context via our own factory, we wrap the original SQL connection string in an EntityConnectionStringBuilder, with the Metadata property pointing to the embedded resources, and use the builders connection string to initialize the DbContext

Initial testing shows an ~80% improvement in startup time - the tricky part here is doing the post-build resource embedding in step 1!

Can anyone provide any clues as to how step 1 could be done in MSBuild? Is there an alternative strategy that would work as well? Basically we want a zero-maintenance solution so that developers don't have to manually do anything other than build their code, with no special deployment considerations either.

EDIT:

We ended up using a new, separate class library project that references the project containing the Code First model. This project contains a T4 template that writes the EDMX from the DbContext into memory, then saves the component parts into project files that are already marked as embedded resources, so we get source control as well.

The build order guarantees that the resources will always be up to date, and the entity connection string references this resources assembly at runtime. The MSBuild integration was done by using the T4 MSBuild integration targets so that the template always runs during a build of the project.

You should certainly be able to do this with MSBuild. You will have to pick up a little bit of build script, but shouldn't be too bad.

How are you doing it now? Do you have a console application that you run to generate the edmx? It sounds like you have already done the hard part -- integrating with MSBuild should be easy. I will assume that you do, and go from there.

btw: One thing to know up front is that you .csproj files are MSBuild scripts, so any custom MSBuild scripting can go into those csproj files.

In order of increasing complexity, you could:

  • Add an "After build" event to your project that executes your console app. This option does not require any MSBuild script -- you just set up an after build event in the project options. It will always run, though. (I don't think you can make a post-build event dependent on configuration), so it could slow down your compile times.
  • You could use the Exec task in MSBuild to execute your console application. This will require a little editing of your csproj file, but you can make it conditional if you need to. Here's a link to the Exec task: http://msdn.microsoft.com/en-us/library/x8zx72cd.aspx If you put it in a target named "AfterBuild", it will automatically execute after your build has completed.
  • You could write your own build task -- this is ac# class that will be loaded and executed during build. This is the most sophisticated way to do it, but it also gives you the most control: http://blogs.msdn.com/b/msbuild/archive/2006/01/21/515834.aspx

One of the nice things about the last option (custom build tasks), is that you can write error messages back into the build process. That should help with getting helpful information if the task fails, and if you use a build server, those messages should be picked up by the server in the same manner as any other build message.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM