如何使用edmgen.exe生成.edmx.diagram文件?

时间:2018-01-20 08:46:45

标签: c# asp.net-mvc visual-studio-2015 entity-framework-6 edmx-designer

使用GitHub中提供的建议,我能够生成ASP.net项目所需的EDMX文件。使用如下命令:

"%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

但是如果我们通过ADO.Net数据模型添加到现有项目来创建EDMX,我不知道如何生成在Visual Studio中生成的附带的 edmx.diagram 文件。

在解决方案资源管理器中,可以在如下位置看到该文件: enter image description here

该文件也可以在Visual Studio中打开,以UML图的形式查看数据库结构,如下所示: enter image description here

此外,为此生成的文件如下所示: enter image description here

我从官方documentation阅读了有关如何使用edmgen.exe生成edmx文件的文档。

我认为在Microsoft文档中遗漏了生成edmx.document文件的文档,我自己无法为此提出解决方案。我已经在这个问题上停留了很长时间,需要帮助才能解决这个问题。

我使用了类似的机制来生成SQL2LINQ转换器项目中所需的文件。拥有这种能力可以带来巨大的帮助。请帮帮我。

编辑1: 我注意到edmx.diagram文件具有这样的属性。我不确定的是,Visual Studio是否在内部使用其他可执行文件来生成图表文件,或者是否存在可以通过命令行创建图表文件的未记录标志。请原谅我的编辑,此信息在最初发布问题时无法获取。

enter image description here

编辑2: 我使用的流程涉及的所有步骤:

步骤1:将我的resource files复制到我需要生成edmx和依赖文件的文件夹中。

注意:这些文件是虚拟文件,将从我在问题中粘贴的命令行命令生成。

步骤2:通过导航到同一路径运行命令行命令。

步骤3:运行命令行后,从用户收集的连接字符串将有助于在同一目录中生成必要的CSDL,SSDL和MSL文件。然后读取文件并将其替换为我在上面链接的resources文件夹中包含的edmx文件。

步骤4:运行textTransform.bat文件,从Texttransform.exe的Windows SDK路径运行texttransform.exe。

观察: 在此阶段,创建6个文件中的5个,即:

  1. .context.tt
  2. .context.cs
  3. 了.Designer.cs
  4. .TT
  5. 的.cs
  6. 对应于用户提供的名称。

    但文件.edmx.diagram丢失了。

    执行第1步到第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;
        }
    }
    

1 个答案:

答案 0 :(得分:2)

简答

要使edmx设计器显示图表,您可以使用以下任一选项:

  • <Designers></Designers>个文件中包含edmx个标记。

  • 包含以下内容的.edmx.designer个文件和.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>
    

长答案

EdmGen.exe不会为您生成edmx,但会生成您自己创建edmx文件所需的所有数据。您可以通过混合csdlssdlmsl来创建edmx文件。

关于图表文件,您应该知道edmx.diagram文件是不必要的。当您使用空edmx标记创建<Diagrams></Diagrams>文件时,第一次在设计器中打开edmx文件时,Visual Studio将为您创建标记的内容。然后,如果您因任何原因想要在单独的文件中使用,您只需右键单击edmx的设计图面并选择Move Diagrams to Separate File即可。

您可以按照以下步骤自行手动(或通过代码)创建edmx文件:

1 - 运行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 - 创建包含以下内容的edmx文件。

请注意,我在本文中使用的edmx内容基于/targetversion:4.5切换。

<?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 - 将edmx中的占位符替换为以下文件的内容(不含<?xml version="1.0" encoding="utf-8"?>):

  • $SSDL$应替换为ssdl文件的内容。
  • $CSDL$应替换为csdl文件的内容。
  • $MSL$应替换为msl文件的内容。

注意

.edmx.designer是可选的,只要在<Diagrams></Diagrams>中有edmx标记,就像我上面分享的一样,那么第一次打开Visual Studio时,图表就是将自动为您创建。同样,出于任何原因,如果你想让图表i成为一个单独的文件,你可以简单地创建一个空的图表文件,在你第一次打开edmx时由VS填充:

<?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>