以编程方式调用EntityDeploy构建任务

编程入门 行业动态 更新时间:2024-10-24 10:21:30
本文介绍了以编程方式调用EntityDeploy构建任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在使用Roslyn编译,发出和运行C#源代码。然而,当面对使用EntityFramework的项目时,我遇到了一个限制。

似乎简单地发出编译是不够的,因为有一个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 文件发生以下情况:

  • EntityDeploySplit 被调用,它读取 .edmx 文件,并确定处理每个文件的结果是否应嵌入到目标程序集中或放在旁边。
  • EntityDeploy 在1. $ NonEmbeddingItems 之间调用,它将 .edmx 文件,并将结果放在 OutputPath
  • EntityDeploy 在 EmbeddingItems 从1.,它分割 .edmx 文件,并将结果放在 EntityDeployIntermediateResourcePath
  • EntityDeploySetLogicalNames 在 EntityDeployIntermediateResourcePath 将每个文件上的元数据 LogicalName 设置为要用于嵌入的逻辑名称(这只是文件的相对路径,来自 EntityDeployIntermediateResourcePath 以斜线替换为点)
  • EntityClean 被删除中间文件
  • 我没有尝试这样做,但应该可以按顺序调用这些,以使用引擎类:

    //实例化一个新的引擎对象引擎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:

  • EntityDeploySplit is invoked, it reads the .edmx files and determines whether the results from processing each one should be embedded in the target assembly or placed alongside.
  • EntityDeploy is called on NonEmbeddingItems from 1., it splits the .edmx files and places the result in OutputPath
  • EntityDeploy is called on EmbeddingItems from 1., it splits the .edmx files and places the result in EntityDeployIntermediateResourcePath
  • EntityDeploySetLogicalNames is called on the files in EntityDeployIntermediateResourcePath to set the metadata LogicalName on each file to the logical name to be used for embedding (It's just the relative path to the file from EntityDeployIntermediateResourcePath with slashes replaced by dots)
  • EntityClean is called to remove the intermediate files
  • 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构建任务

    本文发布于:2023-11-24 08:54:26,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1624549.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:方式   EntityDeploy

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!