Using the suggestion provided in GitHub, I was able to generate the EDMX files needed for an ASP.net project. Using a command like:
"%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:fullgeneration /c:"Data Source=%datasourceserver%; Initial Catalog=School; Integrated Security=SSPI" /project:School /entitycontainer:SchoolEntities /namespace:SchoolModel /language:CSharp
But I don't know how to generate the accompanying edmx.diagram file that gets generated in Visual Studio if we create the EDMX via ADO.Net Data Model addition to existing project.
In the Solution Explorer, the file can be seen in a location like so:
The file can also be opened in Visual studio to see the Database structure in the form of a UML diagram like so:
Additionally the file generated for this gets shown like so:
I read the documentation on how to use edmgen.exe to generate the edmx files as well from the official documentation.
I believe that the documentation to generate the edmx.document file has been missed in the Microsoft documentation and I have been unable to come up with a solution for this by myself. I have been stuck for quite some time on this problem and need help in resolving this.
I have used a similar mechanism to generate files needed in the SQL2LINQ convertor project. Having this capability could help tremendously. Please help me.
Edit 1: I have noticed that the edmx.diagram file has property like so. What I am not sure is if Visual Studio internally uses some other executable to generate the diagram files or if there is an un-documented flag that that can create the diagram files via command line. Please forgive my Edit this information was not avaialable while originally posting the question.
Edit 2: All the steps involved in the process I use:
Step1: Copy my resource files to the folder where I require my edmx and dependency files to be generated.
Note: These files are dummy files and will be generated from the command line command I have pasted in the question.
Step 2: Run the command line command by navigating to the same path.
Step 3: After the command line is run, the connection string collected form the user will help in generating the necessary CSDL, SSDL and MSL files in the same directory. the files are then read and replaced int he edmx files that i have included in the resources folder in the link above.
Step 4: Run The textTransform.bat file to run the texttransform.exe from the Windows SDK path for Texttransform.exe.
Observation: At this stage, 5 of the 6 files are created namely:
corresponding to the name provided by the user.
But the file .edmx.diagram is missing.
Code that does step 1 through 4:
internal class Globals {
public static string EDMXworkingDirectory = @"C:\ERachana\EDMX\EDMXFiles\EDMXParts";
public static bool isEDMXAlreadyGenerated = false;
public static string Server = "",Database = "", UserName = "",Password = "";
public static string ProjectName = "", UserDefinedObjectName = "_appdb", TemporaryDirectoryPath="";
public static string GetSubstringBetweenStrings(string Full, string startMatch, string endMatch) {
int pFrom = Full.IndexOf(startMatch) + startMatch.Length;
int pTo = Full.LastIndexOf(endMatch);
if (pTo > pFrom)
return Full.Substring(pFrom, pTo - pFrom);
else
return "";
}
public static void GenerateORMFiles() {
string workingDirectory = EDMXworkingDirectory;
if (!isEDMXAlreadyGenerated) {
// Show Progress Bar here
try {
isEDMXAlreadyGenerated = true;
Directory.CreateDirectory(@"C:\ERachana");
Directory.CreateDirectory(@"C:\ERachana\EDMX");
Directory.CreateDirectory(@"C:\ERachana\EDMX\EDMXFiles");
Directory.CreateDirectory(workingDirectory);
string CommandToCreateEDMXOnCommandLine = "\"%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\edmgen.exe\" /mode:fullgeneration /c:\"data source = "
+ Server + "; initial catalog = "
+ Database + "; user id = "
+ UserName + "; password = "
+ Password + "; MultipleActiveResultSets = True; persist security info = True; App = EntityFramework\" /project:DataModel /entitycontainer:DBContext /namespace:Models /language:CSharp & exit";
string ResourcesDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Resources\";
string EDMXFileName = "DataModel.edmx";
string ContextFileName = "DataModel.Context.tt";
string TablesFileName = "DataModel.tt";
string EdmxLocation = workingDirectory + @"\" + EDMXFileName;
File.Copy(Path.Combine(ResourcesDirectory, EDMXFileName), EdmxLocation, true);
File.Copy(Path.Combine(ResourcesDirectory, ContextFileName), workingDirectory + @"\" + ContextFileName, true);
File.Copy(Path.Combine(ResourcesDirectory, TablesFileName), workingDirectory + @"\" + TablesFileName, true);
using (var process = new Process()) {
var startInfo = new ProcessStartInfo {
WorkingDirectory = workingDirectory,
WindowStyle = ProcessWindowStyle.Minimized,
CreateNoWindow = true,
RedirectStandardInput = true,
UseShellExecute = false,
FileName = "cmd.exe",
Verb = "runas"
};
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(CommandToCreateEDMXOnCommandLine);
process.WaitForExit();
process.Close();
process.Dispose();
}
string text = File.ReadAllText(EdmxLocation);
string c = "";
c = parseSCMDLFiles(workingDirectory + @"\DataModel.ssdl", "Schema");
text = text.Replace("###StorageModelsSchema", c);
c = parseSCMDLFiles(workingDirectory + @"\DataModel.csdl", "Schema");
text = text.Replace("###ConceptualModelsSchema", c);
c = parseSCMDLFiles(workingDirectory + @"\DataModel.msl", "Mapping");
text = text.Replace("###Mappings", c);
File.WriteAllText(EdmxLocation, text);
string[] fileToBeDeleted = Directory.GetFiles(workingDirectory);
foreach (string filePath in fileToBeDeleted) {
if (filePath.Contains("DataModel.ObjectLayer.cs") || filePath.Contains("DataModel.Views.cs")) {
File.Delete(filePath);
} else {
if (filePath.ToLower().Contains(".edmx") || filePath.ToLower().Contains(".tt") || filePath.ToLower().Contains(".cs"))
continue;
File.Delete(filePath);
}
}
string location = @"C:\ERachana\EDMX";
string TransformFileName = "transform_all.bat";
File.Copy(Path.Combine(ResourcesDirectory, TransformFileName), location + @"\" + TransformFileName, true);
string batFileCommand = "/C " + location + @"\" + TransformFileName;
using (var process = new Process()) {
var startInfo = new ProcessStartInfo() {
WorkingDirectory = location,
WindowStyle = ProcessWindowStyle.Minimized,
CreateNoWindow = true,
UseShellExecute = false,
FileName = @"cmd.exe",
Verb = "runas",
Arguments = batFileCommand
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
process.Close();
process.Dispose();
}
} catch {
MessageBox.Show("Only Projects with MSSQL may be converted to Web Projects");
} finally {
// Close Progressbar here
}
}
}
public static string parseSCMDLFiles(string EDMXDirectoryFile, string tag) {
List<string> lines = File.ReadLines(EDMXDirectoryFile).ToList();
string content = "";
bool flagEnable = false;
foreach (string line in lines) {
if (line.Contains("</" + tag + ">"))
flagEnable = false;
if (flagEnable == true)
content += line + Environment.NewLine;
if (line.Contains("<" + tag))
flagEnable = true;
}
return content;
}
}
Short Answer
To make the edmx
designer show the diagrams, you can use either of the following options:
Having <Designers></Designers>
tag in edmx
file.
Having .edmx.designer
file with following contents and child of .edmx
file:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<edmx:Designer>
<edmx:Diagrams>
</edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>
Long Answer
EdmGen.exe
will not generate edmx
for you, but it generates all data that you need to create an edmx
file yourself. You can simply create edmx file by mixing those csdl
, ssdl
and msl
.
Also about the diagram file, you should know edmx.diagram
file is not necessary. When you create the edmx
file, with empty <Diagrams></Diagrams>
tag, the first time that you open the edmx file in designer, Visual Studio will create the content for the tag for you. Then if for any reason you like to have ot in separate file, you can simply right click on design surface of the edmx and choose Move Diagrams to Separate File
.
You can follow the following steps to create an edmx
file manually (or by code) yourself:
1- Run EdmGen
"%windir%\Microsoft.NET\Framework\v4.0.30319\edmgen.exe" /mode:fullgeneration /c:"Data Source=SERVERNAME; Initial Catalog=DATABASENAME;Integrated Security=SSPI" /project:PROJECT /entitycontainer:CONTAINER /namespace:NAMESPACE /language:CSharp /targetversion:4.5
2- Create an edmx file with following contents.
Please note that the edmx
content which I used in this post, is based on /targetversion:4.5
switch.
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
$SSDL$
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
$CSDL$
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
$MSL$
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
<Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</Connection>
<Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
<DesignerProperty Name="EnablePluralization" Value="true" />
<DesignerProperty Name="IncludeForeignKeysInModel" Value="true" />
<DesignerProperty Name="UseLegacyProvider" Value="false" />
<DesignerProperty Name="CodeGenerationStrategy" Value="None" />
</DesignerInfoPropertySet>
</Options>
<!-- Diagram content (shape and connector positions) -->
<Diagrams></Diagrams>
</Designer>
</edmx:Edmx>
3- Replace the placeholders which you have in edmx with content of the following files (without <?xml version="1.0" encoding="utf-8"?>
):
$SSDL$
should be replaced with content of the ssdl
file.$CSDL$
should be replaced with content of the csdl
file.$MSL$
should be replaced with content of the msl
file.Note
.edmx.designer
is optional and it's enough to have an <Diagrams></Diagrams>
tag in edmx
like what I shared above, then the first time that you open Visual Studio, the diagram will be created for you automatically. Also for any reason if you like to have diagram i a separate file, you can simply create an empty diagram file, which will be filled by VS at the first time that you open edmx:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<edmx:Designer>
<edmx:Diagrams>
</edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>