使用Entity Framework时,是否可以强制生成的实体类为Pascal案例?

时间:2012-03-15 19:25:42

标签: entity-framework entity-framework-4

我正在使用的数据库具有表名,例如“table_name”。这没关系,但我想以“TableName”格式生成类,以C#,Pascal风格工作。

这可能吗?

3 个答案:

答案 0 :(得分:3)

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

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

一些例子:

some_class> SomeClass的

_some_class_> SomeClass的

some_1_said> Some1Said

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

首先可选择不更换下划线,同时仍然将字符串更改为pascal情况(由于列名称如“test_string”和“teststring”,否则两者都解析为“TestString”,导致冲突)。

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

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

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

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

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

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

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

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

  6. 保留复数和外键选项。如果从fresh创建edmx文件,那么 可以选择输入型号名称。您可以更改或保留此内容。

  7. 点击完成。

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

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

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

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

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

  13. 根据申请,应该预期此后的任何应用程序问题 已经做出的改变。

  14. 完整替换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.");
          }
      }
      }
      
    6. 由Chris编辑

      适应Visual Studio 2013&amp; 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(在我的情况下,它没有找到,所以只用FirstOrDefault()替换了First()并添加了简单的null检查)。

答案 1 :(得分:1)

基于Chris&#39;的更新编辑原始答案

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

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

谢谢Chris的意见。我最近重新审视了这个,因为使用此工具的项目已升级到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.");
        }
    }
}

答案 2 :(得分:0)

some_class&gt; SomeClass的
对我不起作用,相反,我得到了:
some_class&gt; SomeClass的

要解决这个问题,我感动了 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);
                }
            }
        }