似乎简单地发出编译是不够的,因为有一个code> EntityDeploy 构建任务,它们在发布后操作DLL。 (我相信它们在发布后将DLL中的元数据工件嵌入)。
在 .csproj 文件我正在处理,我看到以下实体部署任务:
< EntityDeploy Include =Models\Northwind.edmx > < Generator> EntityModelCodeGenerator< / Generator> < LastGenOutput> Northwind.Designer.cs< / LastGenOutput> < / EntityDeploy>是否可以直接调用此构建任务并操作我发出的DLL?
注意:我不想简单地调用 msbuild.exe 或运行 .csproj 文件中的所有内容都有 MSBuild 。我正在构建的项目存在于内存中,但不在磁盘上,因此在我的情况下不起作用。
我试过的内容:我正在尝试学习如何使用 Microsoft.Build.Evaluation 的东西。我可以找到EntityDeploy任务,但是如何调用它(以及我应该提供哪些参数),我感到失落。
var project = new Project(@C:\Users\JoshVarty\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\WebApplication1.csproj); //获取实体部署目标?我不知道这是一个任务还是目标。 var entityDeploy = project.Targets.Where(n => n.Key ==EntityDeploy)。Single(); var projectTargetInstance = entityDeploy.Value;我也试过看看 EntityDeploy 构建任务,因为它存在于磁盘上。
var entityDeployTask = new Microsoft.Data.Entity.Build.Tasks.EntityDeploy() ; entityDeployTask.Sources = //我不知道我可以在哪里得到ITaskItem []我需要 entityDeployTask.EntityDataModelEmbeddedResources = //我不知道我可以在哪里得到ITaskItem [] entityDeployTask.Execute();我同时崭新的 MSBuild , EntityFramework 和 EntityDeploy ,所以请纠正我,如果我滥用条款或完全错误的方式。
解决方案我不熟悉 EntityDeploy ,但我会给我一些可能会帮助你的信息。
如果你看看目标文件,您可以看到有一个 EntityDeploy 目标依赖于 EntityDeploy , EntityDeploySplit , EntityDeploySetLogicalNames 和 EntityClean 任务。
EntityDeploy 目标被调用,列表为 .edmx 文件发生以下情况:
我没有尝试这样做,但应该可以按顺序调用这些,以使用引擎类:
//实例化一个新的引擎对象引擎engine = new Engine(); //指向包含.NET Framework 2.0 CLR和工具的路径 engine.BinPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @\..\Microsoft.NET\Framework\v2.0.50727; var entityDeploySplitTask = new EntityDeploySplit(); entityDeploySplitTask.Sources = new ITaskItem [] { new TaskItem(Model.edmx)// .csproj }中的.edmx文件的路径; entityDeploySplitTask.BuildEngine = engine; entityDeploySplitTask.Execute(); var entityDeployTask = new EntityDeploy(); entityDeployTask.Sources = entityDeploySplitTask.NonEmbeddingItems entityDeployTask.OutputPath =。; //程序集输出文件夹的路径 entityDeployTask.BuildEngine = engine; entityDeployTask.Execute(); var entityDeployTask2 = new EntityDeploy(); entityDeployTask2.Sources = entityDeploySplitTask.EmbeddingItems entityDeployTask2.OutputPath =C:\Temp; //中间文件夹的路径 entityDeployTask2.BuildEngine = engine; entityDeployTask2.Execute(); var entityDeploySetLogicalTask = new EntityDeploySetLogicalNames(); entityDeploySetLogicalTask.Sources = Directory.EnumerateFiles(C:\Temp,*。*,SearchOption.AllDirectories) .Select(f => new TaskItem(f))。ToArray ); entityDeploySetLogicalTask.ResourceOutputPath =C:\Temp; //中间文件夹的路径 entityDeploySetLogicalTask.BuildEngine = engine; entityDeploySetLogicalTask.Execute(); foreach(entityDeploySetLogicalTask.ResourcesToEmbed中的var resourceFile) { var fileName = resourceFile.GetMetadata(Identity); var logicalName = resourceFile.GetMetadata(LogicalName); // TODO:在输出程序集中嵌入使用logicalName的文件名 //您可以将它们作为普通资源嵌入到csc.exe // eg中。 /resource:obj\Debug\edmxResourcesToEmbed\Models\SampleEF.csdl,Models.SampleEF.csdl } // TODO:调用EntityClean,或者只是删除所有文件中间目录
I'm using Roslyn to compile, emit and run C# source code. However, I've run into a limitation when faced with projects that use EntityFramework.
It seems that simply emitting the compilation isn't enough, as there is an EntityDeploy build task that manipulates the DLLs after they've been emitted. (I believe it is embedding Metadata Artifacts in the DLLs after they're emitted).
In the .csproj file I'm processing, I see the following entity deploy task:
<EntityDeploy Include="Models\Northwind.edmx"> <Generator>EntityModelCodeGenerator</Generator> <LastGenOutput>Northwind.Designer.cs</LastGenOutput> </EntityDeploy>Is it possible to invoke this build task this directly and manipulate the DLLs I've emitted?
Note: I don't want to simply call msbuild.exe or run MSBuild on everything in the .csproj file. The projects I'm building exist in memory, but not on disk, so that won't work in my case.
What I've tried:I'm trying to learn how to use the Microsoft.Build.Evaluation stuff. I can find the EntityDeploy task, but I'm at a loss for how to invoke it (and for what parameters I should be providing).
var project = new Project(@"C:\Users\JoshVarty\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\WebApplication1.csproj"); //Get the entity deploy target? I'm not sure if this is a task or target. var entityDeploy = project.Targets.Where(n => n.Key == "EntityDeploy").Single(); var projectTargetInstance = entityDeploy.Value;I've also tried looking at the EntityDeploy build task as it exists on disk.
var entityDeployTask = new Microsoft.Data.Entity.Build.Tasks.EntityDeploy(); entityDeployTask.Sources = //I'm not sure where I can get the ITaskItem[] I need entityDeployTask.EntityDataModelEmbeddedResources = //I'm not sure where I can get the ITaskItem[] entityDeployTask.Execute();I'm simultaneously brand new to MSBuild, EntityFramework and EntityDeploy, so please correct me if I've misused terms or come at this the wrong way altogether.
解决方案I'm not familiar with EntityDeploy, but I'll give some information that I've gathered that might help you.
If you look at the targets file you can see that there's an EntityDeploy target which relies on EntityDeploy, EntityDeploySplit, EntityDeploySetLogicalNames and EntityClean tasks.
When the EntityDeploy target is called with list of .edmx files the following happens:
I haven't tried this, but it should be possible to call these in sequence to get the expected behavior using the Engine class:
// Instantiate a new Engine object Engine engine = new Engine(); // Point to the path that contains the .NET Framework 2.0 CLR and tools engine.BinPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @"\..\Microsoft.NET\Framework\v2.0.50727"; var entityDeploySplitTask = new EntityDeploySplit(); entityDeploySplitTask.Sources = new ITaskItem[] { new TaskItem("Model.edmx")// path to .edmx file from .csproj }; entityDeploySplitTask.BuildEngine = engine; entityDeploySplitTask.Execute(); var entityDeployTask = new EntityDeploy(); entityDeployTask.Sources = entityDeploySplitTask.NonEmbeddingItems entityDeployTask.OutputPath = "."; // path to the assembly output folder entityDeployTask.BuildEngine = engine; entityDeployTask.Execute(); var entityDeployTask2 = new EntityDeploy(); entityDeployTask2.Sources = entityDeploySplitTask.EmbeddingItems entityDeployTask2.OutputPath = "C:\Temp"; // path to an intermediate folder entityDeployTask2.BuildEngine = engine; entityDeployTask2.Execute(); var entityDeploySetLogicalTask = new EntityDeploySetLogicalNames(); entityDeploySetLogicalTask.Sources = Directory.EnumerateFiles("C:\Temp", "*.*", SearchOption.AllDirectories) .Select(f => new TaskItem(f)).ToArray(); entityDeploySetLogicalTask.ResourceOutputPath = "C:\Temp"; // path to the intermediate folder entityDeploySetLogicalTask.BuildEngine = engine; entityDeploySetLogicalTask.Execute(); foreach(var resourceFile in entityDeploySetLogicalTask.ResourcesToEmbed) { var fileName = resourceFile.GetMetadata("Identity"); var logicalName = resourceFile.GetMetadata("LogicalName"); //TODO: Embed filename using logicalName in the output assembly //You can embed them as normal resources by passing /resource to csc.exe //eg. /resource:obj\Debug\edmxResourcesToEmbed\Models\SampleEF.csdl,Models.SampleEF.csdl } //TODO: call EntityClean or just remove all files from the intermediate directory
更多推荐
以编程方式调用EntityDeploy构建任务
发布评论