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
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:
.edmx
files and determines whether the results from processing each one should be embedded in the target assembly or placed alongside.NonEmbeddingItems
from 1., it splits the .edmx
files and places the result in OutputPath
EmbeddingItems
from 1., it splits the .edmx
files and places the result in EntityDeployIntermediateResourcePath
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)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
Try the following:
var mockObject = new Mock<IBuildEngine>();
IBuildEngine engine = mockObject.Object;
var entityDeployTask = new EntityDeploy();
entityDeployTask.Sources = new ITaskItem[]
{
new TaskItem(@"path to edmx\Model1.edmx")
};
entityDeployTask.OutputPath = @"C:\";
entityDeployTask.BuildEngine = engine;
entityDeployTask.Execute();
The output path doesn't seem to be picked up, but if it's empty then an error is logged. You can see this if you implement your own IBuildEngine
and log the errors. The result of the process will be three files next to the edmx: "Model1.ssdl", "Model1.csdl", "Model1.msdl". These files need to be passed to CSC as embedded resources, at least that's what the original targets file seems to do.
Hope it helps, and at least gets you started.