简体   繁体   English

如何在Code First程序集中嵌入EDMX?

[英]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. 我们在EF6.1中使用Code First - 我们的模型现在超过300多个表,启动时间很荒谬。 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. 我们已经尝试过预生成视图,但它没有多大帮助,它是Code First管道中的模型编译,占用了大部分时间。

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. 我们将尝试使用Database / Model First方法通过使用具有到CSDL,SSDL和MDL文件的元数据链接的实体连接字符串而不是直接SQL连接来初始化上下文。 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 在编译包含Code First模型的项目之后,运行后构建任务,从DbContext生成EDMX文件,将其拆分为组件CSDL,SSDL和MDL文件,并将这些文件作为资源嵌入到程序集中
  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 当我们通过自己的工厂创建上下文时,我们将原始SQL连接字符串包装在EntityConnectionStringBuilder中,Metadata属性指向嵌入的资源,并使用构建器连接字符串初始化DbContext

Initial testing shows an ~80% improvement in startup time - the tricky part here is doing the post-build resource embedding in step 1! 初始测试显示启动时间缩短了约80% - 这里的棘手部分是在第1步中进行构建后资源嵌入!

Can anyone provide any clues as to how step 1 could be done in MSBuild? 任何人都可以提供任何关于如何在MSBuild中完成第1步的线索吗? 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. 我们最终使用了一个新的独立类库项目,该项目引用了包含Code First模型的项目。 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. 该项目包含一个T4模板,它将EDMX从DbContext写入内存,然后将组件部分保存到已标记为嵌入资源的项目文件中,因此我们也获得了源代码控制。

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. 通过使用T4 MSBuild集成目标完成MSBuild集成,以便模板始终在项目构建期间运行。

You should certainly be able to do this with MSBuild. 您当然可以使用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? 您是否有运行的控制台应用程序来生成edmx? It sounds like you have already done the hard part -- integrating with MSBuild should be easy. 听起来你已经完成了很难 - 与MSBuild集成应该很容易。 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. 顺便说一句:要知道的一件事是.csproj文件 MSBuild脚本,因此任何自定义MSBuild脚本都可以进入那些csproj文件。

In order of increasing complexity, you could: 为了增加复杂性,您可以:

  • Add an "After build" event to your project that executes your console app. 将“After build”事件添加到执行控制台应用程序的项目中。 This option does not require any MSBuild script -- you just set up an after build event in the project options. 此选项不需要任何MSBuild脚本 - 您只需在项目选项中设置After build事件。 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. 您可以使用MSBuild中的Exec任务来执行您的控制台应用程序。 This will require a little editing of your csproj file, but you can make it conditional if you need to. 这需要对csproj文件进行一些编辑,但如果需要,可以将其设置为条件。 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. 以下是Exec任务的链接: http//msdn.microsoft.com/en-us/library/x8zx72cd.aspx如果将其放在名为“AfterBuild”的目标中,它将在构建完成后自动执行。
  • You could write your own build task -- this is ac# class that will be loaded and executed during build. 您可以编写自己的构建任务 - 这是将在构建期间加载和执行的ac#类。 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 这是最复杂的方法,但它也为您提供最大的控制权: 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. 如果任务失败,这应该有助于获取有用的信息,如果您使用构建服务器,那么服务器应该以与任何其他构建消息相同的方式获取这些消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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