【问题标题】:When working with Entity Framework, is it possible to force generated entity classes to be Pascal case?使用实体框架时,是否可以强制生成的实体类为 Pascal 案例?
【发布时间】:2012-03-15 19:25:41
【问题描述】:

我正在处理的数据库具有诸如“table_name”之类的表名。这很好,但我想生成格式为“TableName”的类,以便在 C#、Pascal 风格中使用。

这可能吗?

【问题讨论】:

    标签: entity-framework entity-framework-4


    【解决方案1】:

    更新:要与 EF6 一起使用,请参阅此页面上的其他答案。

    感谢Alex's answer,我现在已将此代码扩展为解决此问题的完整工作解决方案。由于我花了一天的大部分时间,所以我在这里发帖以帮助其他面临同样挑战的人。这包括一个用于操作 edmx 文件的完整类(这里没有漂亮的代码),它通过了对不同输入字符串的相当详细的单元测试:

    几个例子:

    some_class > SomeClass

    _some_class_ > SomeClass

    some_1_said > Some1Said

    我还有一些其他问题需要处理:

    首先可选地不替换下划线,同时仍将字符串更改为帕斯卡大小写(由于“test_string”和“teststring”等列名,否则它们都解析为“TestString”,导致冲突)。

    其次,我这里的代码采用了一个输入参数,该参数修改了生成的对象上下文类名。

    最后,我最初不确定如何在修改 edmx 后更新设计器文件,所以我已经包含了确切的步骤。我建议在 Visual Studio 中创建一个预构建步骤,这样可以节省一些从修改后的数据库架构进行更新的剩余工作。

    更新 EDMX 文件以反映数据库更改

    1. 双击 edmx 文件以显示设计图面。

    2. 右键单击设计图面并选择“从数据库更新模型”。

    3. 选择“是在连接字符串中包含敏感信息”。

    4. 取消选中“在 App Config 中保存实体连接设置”(我们已经有了这些)。

    5. 选择适当的数据库。在添加屏幕中选择表格、视图等。

    6. 将复数和外键选项保留为选中状态。如果从新鲜创建 edmx 文件,您 可以选择输入型号名称。您可以更改或保留它。

    7. 点击完成。

    8. 在 edmx 文件上运行以下代码。

    9. 根据应用程序的状态,您可能会在此处看到错误,直到下一步。

    10. 右键单击要更新的 edmx 文件,然后在 Visual Studio 中选择“运行自定义工具”。这将导致 要更新的 Designer.cs (C#) 文件。

    11. 运行构建以检查没有编译器错误。

    12. 运行测试以确保应用程序正常运行。

    13. 根据应用程序应预料到以下任何应用程序问题 已进行的更改。

    替换整个 edmx 文件。

    1. 删除 edmx 文件,同时带上设计器文件。

    2. 右键实体文件夹

    3. 从创建文件对话框中,选择 ADO.NET 实体数据模型。根据您希望用于对象上下文的类名来命名它(重要)。 此值在连接字符串中引用,因此请查看您的应用配置以防出现问题。

    4. 在选择模型内容中,选择从数据库生成。

    5. 按照上述步骤 3 中的说明进行操作。

      using System;    
      using System.IO;    
      using System.Linq;    
      using System.Text;    
      using System.Xml;    
      using System.Xml.Linq;
      
      namespace EdmxStringFormatter
      {
          public class Program
          {
              static void Main(string[] args)
              {
                  if (args.Length < 1) return;
      
              string filePath = args[0];
      
              string entityName = null;
      
              // Optionally do not replace underscores which 
              // helps with naming collisions with siimilarly named
              // columns on some database tables.
      
              bool replaceUnderscores = true;
      
              // Allow for the replacement of the object context class name, which is useful
              // where multiple databases have edmx files.
      
              bool doEntityNameReplace = false;
      
              if (args.Length > 1)
              {
                  entityName = args[1];
                  doEntityNameReplace = true;
              }
      
              if (args.Length > 2)
              {
                  replaceUnderscores = args[2] != "0";
              }
      
              if (!File.Exists(filePath))
              {
                  StopWithMessage("Could not find specified file.");
                  return;
              }
              if (Path.GetExtension(filePath) != ".edmx")
              {
                  StopWithMessage("This works only on EDMX files.");
                  return;
              }
      
              // Processing:
      
              Console.WriteLine("Creating backup: " + Path.ChangeExtension(filePath, ".bak"));
              File.Copy(filePath, Path.ChangeExtension(filePath, ".bak"), true);
      
              Console.WriteLine("Reading target document...");
      
              XDocument xdoc = XDocument.Load(filePath);
      
              const string CSDLNamespace = "http://schemas.microsoft.com/ado/2008/09/edm";
              const string MSLNamespace = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";
              const string DiagramNamespace = "http://schemas.microsoft.com/ado/2008/10/edmx";
      
              const string CSNameSpace = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";
      
              XElement csdl = xdoc.Descendants(XName.Get("Schema", CSDLNamespace)).First();
              XElement msl = xdoc.Descendants(XName.Get("Mapping", MSLNamespace)).First();
              XElement designerDiagram = xdoc.Descendants(XName.Get("Diagram", DiagramNamespace)).First();
      
              //modifications for renaming everything, not just table names:
      
              #region CSDL2
      
              Console.WriteLine("Modifying CSDL...");
              Console.WriteLine(" - modifying entity sets...");
      
              foreach (var entitySet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("EntitySet", CSDLNamespace)))
              {
                  entitySet.Attribute("Name").Value = FormatString(entitySet.Attribute("Name").Value, replaceUnderscores);
                  entitySet.Attribute("EntityType").Value = FormatString(entitySet.Attribute("EntityType").Value, replaceUnderscores);
              }
      
              Console.WriteLine(" - modifying association sets...");
              foreach (var associationSet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("AssociationSet", CSDLNamespace)))
              {
                  foreach (var end in associationSet.Elements(XName.Get("End", CSDLNamespace)))
                  {
                      end.Attribute("EntitySet").Value = FormatString(end.Attribute("EntitySet").Value, replaceUnderscores);
                  }
              }
      
              Console.WriteLine(" - modifying entity types...");
              foreach (var entityType in csdl.Elements(XName.Get("EntityType", CSDLNamespace)))
              {
                  entityType.Attribute("Name").Value = FormatString(entityType.Attribute("Name").Value, replaceUnderscores);
      
                  foreach (var key in entityType.Elements(XName.Get("Key", CSDLNamespace)))
                  {
                      foreach (var propertyRef in key.Elements(XName.Get("PropertyRef", CSDLNamespace)))
                      {
                          propertyRef.Attribute("Name").Value = FormatString(propertyRef.Attribute("Name").Value, replaceUnderscores);
                      }
                  }
      
                  foreach (var property in entityType.Elements(XName.Get("Property", CSDLNamespace)))
                  {
                      property.Attribute("Name").Value = FormatString(property.Attribute("Name").Value, replaceUnderscores);
                  }
      
                  foreach (var navigationProperty in entityType.Elements(XName.Get("NavigationProperty", CSDLNamespace)))
                  {
                      navigationProperty.Attribute("Name").Value = FormatString(navigationProperty.Attribute("Name").Value, replaceUnderscores);
                  }
      
              }
      
              Console.WriteLine(" - modifying associations...");
              foreach (var association in csdl.Elements(XName.Get("Association", CSDLNamespace)))
              {
                  foreach (var end in association.Elements(XName.Get("End", CSDLNamespace)))
                  {
                      end.Attribute("Type").Value = FormatString(end.Attribute("Type").Value, replaceUnderscores);
                  }
                  foreach (var propref in association.Descendants(XName.Get("PropertyRef", CSDLNamespace)))
                  {
                      //propertyrefs are contained in constraints
                      propref.Attribute("Name").Value = FormatString(propref.Attribute("Name").Value, replaceUnderscores);
                  }
              }
      
              #endregion
      
              #region MSL2
      
              Console.WriteLine("Modifying MSL...");
              Console.WriteLine(" - modifying entity set mappings...");
      
              foreach (var entitySetMapping in msl.Element(XName.Get("EntityContainerMapping", MSLNamespace)).Elements(XName.Get("EntitySetMapping", MSLNamespace)))
              {
                  entitySetMapping.Attribute("Name").Value = FormatString(entitySetMapping.Attribute("Name").Value, replaceUnderscores);
      
                  foreach (var entityTypeMapping in entitySetMapping.Elements(XName.Get("EntityTypeMapping", MSLNamespace)))
                  {
                      entityTypeMapping.Attribute("TypeName").Value = FormatString(entityTypeMapping.Attribute("TypeName").Value, replaceUnderscores);
                      foreach
                      (var scalarProperty in
                      (entityTypeMapping.Element(XName.Get("MappingFragment", MSLNamespace))).Elements(XName.Get("ScalarProperty", MSLNamespace))
                      )
                      {
                          scalarProperty.Attribute("Name").Value = FormatString(scalarProperty.Attribute("Name").Value, replaceUnderscores);
                      }
                  }
              }
      
              Console.WriteLine(" - modifying association set mappings...");
      
              foreach (var associationSetMapping in msl.Element(XName.Get("EntityContainerMapping", MSLNamespace)).Elements(XName.Get("AssociationSetMapping", MSLNamespace)))
              {
                  foreach (var endProperty in associationSetMapping.Elements(XName.Get("EndProperty", MSLNamespace)))
                  {
                      foreach (var scalarProperty in endProperty.Elements(XName.Get("ScalarProperty", MSLNamespace)))
                      {
                          scalarProperty.Attribute("Name").Value = FormatString(scalarProperty.Attribute("Name").Value, replaceUnderscores);
                      }
                  }
              }
              #endregion
      
      
              #region Designer
      
              Console.WriteLine("Modifying designer content...");
              foreach (var item in designerDiagram.Elements(XName.Get("EntityTypeShape", DiagramNamespace)))
              {
                  item.Attribute("EntityType").Value = FormatString(item.Attribute("EntityType").Value, replaceUnderscores);
              }
      
              #endregion
      
              // Optionally replace the entity name in case the default of "Entity" is not
              // sufficient for your needs.
      
              if (doEntityNameReplace)
              {
                  Console.WriteLine("Modifying entity name refs...");
      
                  // CSDL
                  xdoc.Descendants(XName.Get("EntityContainer", CSDLNamespace)).First().Attribute("Name").Value = entityName;
      
                  // Diagram 
                  xdoc.Descendants(XName.Get("Diagram", DiagramNamespace)).First().Attribute("Name").Value = entityName;
      
                  // Diagram 
                  xdoc.Descendants(XName.Get("EntityContainerMapping", CSNameSpace)).First().Attribute("CdmEntityContainer").Value = entityName;
              }
      
              Console.WriteLine("Writing result...");
      
              using (XmlTextWriter writer = new XmlTextWriter(filePath, Encoding.Default))
              {
                  writer.Formatting = Formatting.Indented;
                  xdoc.WriteTo(writer);
              }
          }
      
          /// <summary>
          /// Formats the string to pascal case, additionally checking for a period
          /// in the string (in which case it skips past the period, which indicates 
          /// the use of namespace in a string.
          /// </summary>
          /// <param name="str"></param>
          /// <param name="replaceUnderscores"></param>
          /// <returns></returns>
          private static string FormatString(string str, bool replaceUnderscores = true)
          {
              char[] chars = str.ToCharArray();
      
              var sb = new StringBuilder();
      
              bool previousCharWasUpper = false;
              bool lastOperationWasToLower = false;
      
              int startPos = 0;
      
              if (str.Contains("."))
              {
                  if (str.IndexOf(".") < (str.Length - 1))
                  {
                      startPos = str.IndexOf(".") + 1;
                  }
      
                  sb.Append(str.Substring(0, startPos));
              }
      
              for (int i = startPos; i < chars.Length; i++)
              {
                  char character = chars[i];
      
                  if (Char.IsLetter(character))
                  {
                      if (Char.IsLower(character))
                      {
                          bool toUpper = false;
      
                          if (i > 0)
                          {
                              // Look at the previous char to see if not a letter
      
                              if (!Char.IsLetter(chars[i - 1]))
                              {
                                  toUpper = true;
                              }
                          }
      
                          if (i == 0 || toUpper)
                          {
                              character = Char.ToUpper(character);
      
                              lastOperationWasToLower = false;
                          }
                      }
                      else // IsUpper = true
                      {
                          if (previousCharWasUpper || lastOperationWasToLower)
                          {
                              character = Char.ToLower(character);
      
                              lastOperationWasToLower = true;
                          }
                      }
      
                      previousCharWasUpper = Char.IsUpper(character);
      
                      sb.Append(character);
                  }
                  else
                  {
                      if (Char.IsDigit(character))
                      {
                          sb.Append(character);
      
                          previousCharWasUpper = false;
                          lastOperationWasToLower = false;
                      }
                      else if(!replaceUnderscores)
                      {
                          if(character == '_')
                          {
                              sb.Append(character);
                          }
                      }
                  }
              }
      
              return sb.ToString();
      
          }
      
          private static void StopWithMessage(string str)
          {
              Console.WriteLine(str);
      
              Console.ReadLine();
      
              throw new InvalidOperationException("Cannot continue.");
          }
      }
      }
      

    克里斯编辑

    适应 Visual Studio 2013 & EF6

    代码命名空间需要稍作调整才能与 EF6 一起使用:

        const string CSDLNamespace = "http://schemas.microsoft.com/ado/2009/11/edm";
        const string MSLNamespace = "http://schemas.microsoft.com/ado/2009/11/mapping/cs";
        const string DiagramNamespace = "http://schemas.microsoft.com/ado/2009/11/edmx";
    
        const string CSNameSpace = "http://schemas.microsoft.com/ado/2009/11/mapping/cs";
    

    另外,您需要注意 DesignerDiagram(在我的情况下,它没有找到,所以只需将 First() 替换为 FirstOrDefault() 并添加简单的空检查)。

    【讨论】:

    • 我已经完成了与指定相同的操作...但实体名称仍为小写...在执行控制台应用程序时需要您的帮助...请帮助我
    • 很难说你的问题出在哪里。请检查您的步骤并详细说明。
    • 我已经创建了控制台应用程序。在 Program.cs 中添加了你的整个代码然后我发布了代码来为应用程序生成 exe。然后在工具菜单中我添加了一个新工具对于命令选项卡,我选择了控制台应用程序的 exe,然后在参数中我将其设置为“$(ItemPath)”并在初始目录“$(ItemDir)”中...检查了参数选项的提示并单击确定并完成...
    • 我是否正确完成了我在之前评论中提到的步骤...如果我有任何错误,请纠正我...帮助我,我已按照您指定的方式完成了所有操作,但不能t实现解决方案
    • 如果有人遇到图表无法正常工作的问题:VS2013 喜欢将图表从 edmx 文件中分离出来,因此定义在 YourEdmx.edmx.diagram 中。解析器需要承认它。我确实意识到这是旧代码,但我在这个问题上花了很多钱,这是我找到的最佳答案。
    【解决方案2】:

    根据 Chris 对原始答案的编辑进行更新

    这是在 Entity Framework 6 上下文中使用的完整 C# .edmx 修改代码(原始答案适用于 EF4)。

    (由于每个答案的字符数限制,附加答案而不是编辑)

    感谢克里斯的意见。我最近重新审视了这个,因为使用此工具的项目已升级到 EF6。下面复制了用于 EF6 的完整代码。

    请注意,此程序代码现在在两个文件上运行 - .edmx 和 .edmx.diagram 文件。 Visual Studio 2013 将图表拆分为单独的文件,这需要编辑,否则表格/实体表示将不会显示在 .edmx 设计器表面上。设计器文件的文件路径被接受为第二个参数。

    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace EdmxStringFormatter
    {
        public class Program
        {
            static void Main(string[] args)
            {
                if (args.Length < 1) return;
    
                string filePath = args[0];
                string designerFilePath = null;
    
                string entityName = null;
    
                // Optionally do not replace underscores which 
                // helps with naming collisions with siimilarly named
                // columns on some database tables.
    
                bool replaceUnderscores = true;
    
                // Allow for the replacement of the object context class name, which is useful
                // where multiple databases have edmx files.
    
                bool doEntityNameReplace = false;
    
                if (args.Length > 1)
                {
                    designerFilePath = args[1];
                }
    
                if (args.Length > 2)
                {
                    entityName = args[2];
                    doEntityNameReplace = true;
                }
    
                if (args.Length > 3)
                {
                    replaceUnderscores = args[3] != "0";
                }
    
                if (!File.Exists(filePath))
                {
                    StopWithMessage("Could not find specified file.");
                    return;
                }
                if (Path.GetExtension(filePath) != ".edmx")
                {
                    StopWithMessage("This works only on EDMX files.");
                    return;
                }
    
                TransformEdmx(filePath, replaceUnderscores, doEntityNameReplace, entityName);
                TransformEdmxDiagram(designerFilePath, replaceUnderscores);
            }
    
            private static void TransformEdmx(string filePath, bool replaceUnderscores, bool doEntityNameReplace, string entityName)
            {
                // Processing:
    
                Console.WriteLine("Creating backup: " + Path.ChangeExtension(filePath, ".bak"));
                File.Copy(filePath, Path.ChangeExtension(filePath, ".bak"), true);
    
                Console.WriteLine("Reading target document...");
    
                XDocument xdoc = XDocument.Load(filePath);
    
                //const string CSDLNamespace = "http://schemas.microsoft.com/ado/2008/09/edm";
                //const string MSLNamespace = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";
                //const string DiagramNamespace = "http://schemas.microsoft.com/ado/2008/10/edmx";
    
                //const string CSNameSpace = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";
    
                const string CSDLNamespace = "http://schemas.microsoft.com/ado/2009/11/edm";
                const string MSLNamespace = "http://schemas.microsoft.com/ado/2009/11/mapping/cs";
                const string DiagramNamespace = "http://schemas.microsoft.com/ado/2009/11/edmx";
    
                const string CSNameSpace = "http://schemas.microsoft.com/ado/2009/11/mapping/cs";
    
                XElement csdl = xdoc.Descendants(XName.Get("Schema", CSDLNamespace)).First();
                XElement msl = xdoc.Descendants(XName.Get("Mapping", MSLNamespace)).First();
    
                //modifications for renaming everything, not just table names:
    
                #region CSDL2
    
                Console.WriteLine("Modifying CSDL...");
                Console.WriteLine(" - modifying entity sets...");
    
                foreach (
                    var entitySet in
                        csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("EntitySet", CSDLNamespace)))
                {
                    entitySet.Attribute("Name").Value = FormatString(entitySet.Attribute("Name").Value, replaceUnderscores);
                    entitySet.Attribute("EntityType").Value = FormatString(entitySet.Attribute("EntityType").Value,
                        replaceUnderscores);
                }
    
                Console.WriteLine(" - modifying association sets...");
                foreach (
                    var associationSet in
                        csdl.Element(XName.Get("EntityContainer", CSDLNamespace))
                            .Elements(XName.Get("AssociationSet", CSDLNamespace)))
                {
                    foreach (var end in associationSet.Elements(XName.Get("End", CSDLNamespace)))
                    {
                        end.Attribute("EntitySet").Value = FormatString(end.Attribute("EntitySet").Value, replaceUnderscores);
                    }
                }
    
                Console.WriteLine(" - modifying entity types...");
                foreach (var entityType in csdl.Elements(XName.Get("EntityType", CSDLNamespace)))
                {
                    entityType.Attribute("Name").Value = FormatString(entityType.Attribute("Name").Value, replaceUnderscores);
    
                    foreach (var key in entityType.Elements(XName.Get("Key", CSDLNamespace)))
                    {
                        foreach (var propertyRef in key.Elements(XName.Get("PropertyRef", CSDLNamespace)))
                        {
                            propertyRef.Attribute("Name").Value = FormatString(propertyRef.Attribute("Name").Value,
                                replaceUnderscores);
                        }
                    }
    
                    foreach (var property in entityType.Elements(XName.Get("Property", CSDLNamespace)))
                    {
                        property.Attribute("Name").Value = FormatString(property.Attribute("Name").Value, replaceUnderscores);
                    }
    
                    foreach (var navigationProperty in entityType.Elements(XName.Get("NavigationProperty", CSDLNamespace)))
                    {
                        navigationProperty.Attribute("Name").Value = FormatString(navigationProperty.Attribute("Name").Value,
                            replaceUnderscores);
                    }
                }
    
                Console.WriteLine(" - modifying associations...");
                foreach (var association in csdl.Elements(XName.Get("Association", CSDLNamespace)))
                {
                    foreach (var end in association.Elements(XName.Get("End", CSDLNamespace)))
                    {
                        end.Attribute("Type").Value = FormatString(end.Attribute("Type").Value, replaceUnderscores);
                    }
                    foreach (var propref in association.Descendants(XName.Get("PropertyRef", CSDLNamespace)))
                    {
                        //propertyrefs are contained in constraints
                        propref.Attribute("Name").Value = FormatString(propref.Attribute("Name").Value, replaceUnderscores);
                    }
                }
    
                #endregion
    
                #region MSL2
    
                Console.WriteLine("Modifying MSL...");
                Console.WriteLine(" - modifying entity set mappings...");
    
                foreach (
                    var entitySetMapping in
                        msl.Element(XName.Get("EntityContainerMapping", MSLNamespace))
                            .Elements(XName.Get("EntitySetMapping", MSLNamespace)))
                {
                    entitySetMapping.Attribute("Name").Value = FormatString(entitySetMapping.Attribute("Name").Value,
                        replaceUnderscores);
    
                    foreach (var entityTypeMapping in entitySetMapping.Elements(XName.Get("EntityTypeMapping", MSLNamespace)))
                    {
                        entityTypeMapping.Attribute("TypeName").Value = FormatString(entityTypeMapping.Attribute("TypeName").Value,
                            replaceUnderscores);
                        foreach
                            (var scalarProperty in
                                (entityTypeMapping.Element(XName.Get("MappingFragment", MSLNamespace))).Elements(
                                    XName.Get("ScalarProperty", MSLNamespace))
                            )
                        {
                            scalarProperty.Attribute("Name").Value = FormatString(scalarProperty.Attribute("Name").Value,
                                replaceUnderscores);
                        }
                    }
                }
    
                Console.WriteLine(" - modifying association set mappings...");
    
                foreach (
                    var associationSetMapping in
                        msl.Element(XName.Get("EntityContainerMapping", MSLNamespace))
                            .Elements(XName.Get("AssociationSetMapping", MSLNamespace)))
                {
                    foreach (var endProperty in associationSetMapping.Elements(XName.Get("EndProperty", MSLNamespace)))
                    {
                        foreach (var scalarProperty in endProperty.Elements(XName.Get("ScalarProperty", MSLNamespace)))
                        {
                            scalarProperty.Attribute("Name").Value = FormatString(scalarProperty.Attribute("Name").Value,
                                replaceUnderscores);
                        }
                    }
                }
    
                #endregion
    
                // Optionally replace the entity name in case the default of "Entity" is not
                // sufficient for your needs.
    
                if (doEntityNameReplace)
                {
                    Console.WriteLine("Modifying entity name refs...");
    
                    // CSDL
                    xdoc.Descendants(XName.Get("EntityContainer", CSDLNamespace)).First().Attribute("Name").Value = entityName;
    
                    // Diagram 
                    var diagramDescendants = xdoc.Descendants(XName.Get("Diagram", DiagramNamespace)).FirstOrDefault();
    
                    if (diagramDescendants != null)
                    {
                        diagramDescendants.Attribute("Name").Value = entityName;
                    }
    
                    // Diagram 
                    xdoc.Descendants(XName.Get("EntityContainerMapping", CSNameSpace)).First().Attribute("CdmEntityContainer").Value
                        = entityName;
                }
    
                Console.WriteLine("Writing result...");
    
                using (XmlTextWriter writer = new XmlTextWriter(filePath, Encoding.Default))
                {
                    writer.Formatting = Formatting.Indented;
                    xdoc.WriteTo(writer);
                }
            }
    
            private static void TransformEdmxDiagram(string filePath, bool replaceUnderscores)
            {
                // Processing:
    
                Console.WriteLine("Creating backup: " + Path.ChangeExtension(filePath, ".bak"));
                File.Copy(filePath, Path.ChangeExtension(filePath, ".bak"), true);
    
                Console.WriteLine("Reading target document...");
    
                XDocument xdoc = XDocument.Load(filePath);
    
                const string DiagramNamespace = "http://schemas.microsoft.com/ado/2009/11/edmx";
    
                XElement designerDiagram = xdoc.Descendants(XName.Get("Diagram", DiagramNamespace)).FirstOrDefault();
    
    
                #region Designer
    
                Console.WriteLine("Modifying designer content...");
    
                if (designerDiagram != null)
                {
                    foreach (var item in designerDiagram.Elements(XName.Get("EntityTypeShape", DiagramNamespace)))
                    {
                        item.Attribute("EntityType").Value = FormatString(item.Attribute("EntityType").Value, replaceUnderscores);
                    }
                }
    
                #endregion
    
                Console.WriteLine("Writing result...");
    
                using (XmlTextWriter writer = new XmlTextWriter(filePath, Encoding.Default))
                {
                    writer.Formatting = Formatting.Indented;
                    xdoc.WriteTo(writer);
                }
            }
    
            /// <summary>
            /// Formats the string to pascal case, additionally checking for a period
            /// in the string (in which case it skips past the period, which indicates 
            /// the use of namespace in a string.
            /// </summary>
            /// <param name="str"></param>
            /// <param name="replaceUnderscores"></param>
            /// <returns></returns>
            private static string FormatString(string str, bool replaceUnderscores = true)
            {
                char[] chars = str.ToCharArray();
    
                var sb = new StringBuilder();
    
                bool previousCharWasUpper = false;
                bool lastOperationWasToLower = false;
    
                int startPos = 0;
    
                if (str.Contains("."))
                {
                    if (str.IndexOf(".") < (str.Length - 1))
                    {
                        startPos = str.IndexOf(".") + 1;
                    }
    
                    sb.Append(str.Substring(0, startPos));
                }
    
                for (int i = startPos; i < chars.Length; i++)
                {
                    char character = chars[i];
    
                    if (Char.IsLetter(character))
                    {
                        if (Char.IsLower(character))
                        {
                            bool toUpper = false;
    
                            if (i > 0)
                            {
                                // Look at the previous char to see if not a letter
    
                                if (!Char.IsLetter(chars[i - 1]))
                                {
                                    toUpper = true;
                                }
                            }
    
                            if (i == 0 || toUpper)
                            {
                                character = Char.ToUpper(character);
    
                                lastOperationWasToLower = false;
                            }
                        }
                        else // IsUpper = true
                        {
                            if (previousCharWasUpper || lastOperationWasToLower)
                            {
                                character = Char.ToLower(character);
    
                                lastOperationWasToLower = true;
                            }
                        }
    
                        previousCharWasUpper = Char.IsUpper(character);
    
                        sb.Append(character);
                    }
                    else
                    {
                        if (Char.IsDigit(character))
                        {
                            sb.Append(character);
    
                            previousCharWasUpper = false;
                            lastOperationWasToLower = false;
                        }
                        else if (!replaceUnderscores)
                        {
                            if (character == '_')
                            {
                                sb.Append(character);
                            }
                        }
                    }
                }
    
                return sb.ToString();
    
            }
    
            private static void StopWithMessage(string str)
            {
                Console.WriteLine(str);
    
                Console.ReadLine();
    
                throw new InvalidOperationException("Cannot continue.");
            }
        }
    }
    

    【讨论】:

    • 我只是想让您知道,我发现这非常有用。我将把它放到我的 GitHub 中,这样我就会一直拥有它的副本。我将链接回此处以获得功劳。谢谢!
    【解决方案3】:

    some_class > SomeClass
    对我没有用,而是我得到了:
    some_class > 某类

    为了修复它,我搬家了
    previousCharWasUpper = false;
    几行。它接近旧代码块的末尾。

            else
            {
                if (Char.IsDigit(character))
                {
                    sb.Append(character);
    
                    previousCharWasUpper = false;
                    lastOperationWasToLower = false;
                }
                else if(!replaceUnderscores)
                {
                    if(character == '_')
                    {
                        sb.Append(character);
                    }
                }
            }
    

    改为:

            else
            {
                previousCharWasUpper = false;
    
                if (Char.IsDigit(character))
                {
                    sb.Append(character);
    
                    lastOperationWasToLower = false;
                }
                else if(!replaceUnderscores)
                {
                    if(character == '_')
                    {
                        sb.Append(character);
                    }
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多