Invoke EntityDeploy build task programmatically

后端 未结 2 1389
名媛妹妹
名媛妹妹 2021-02-14 19:11

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 e

2条回答
  •  名媛妹妹
    2021-02-14 19:49

    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:

    1. 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.
    2. EntityDeploy is called on NonEmbeddingItems from 1., it splits the .edmx files and places the result in OutputPath
    3. EntityDeploy is called on EmbeddingItems from 1., it splits the .edmx files and places the result in EntityDeployIntermediateResourcePath
    4. 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)
    5. 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
    

提交回复
热议问题