【问题标题】:Entity Framework - Capitalizing first property name letter实体框架 - 大写第一个属性名称字母
【发布时间】:2011-06-28 10:33:55
【问题描述】:

一般来说,我倾向于使用以下驼峰式命名约定来命名我的 sql 数据库列:

camelCase(注意第一个字母是小写的)。

但在使用 C# 时,我喜欢按以下约定命名对象的公共属性:

PascalCase(注意第一个大写)。

Entity Framework 的默认行为是命名创建的类的属性以匹配它们在数据库中的相对列名。

项目/解决方案级别中是否有任何属性可以更改以解决此问题?

【问题讨论】:

  • 是 dbFirst approch ryt 吗?
  • 我曾尝试在 ADO.NET 实体数据模型设计器(双击 .edmx 文件)上重命名表,但如果我在其中重命名表,则这些方法也会重命名。例如,如果我将表 customer 重命名为 Customer,那么方法 AddTocustomers get 重命名为 AddToCustomers1 为什么 Visual Studio 会放置 1?
  • 只需要修改属性名 ryt ?

标签: c# .net sql entity-framework


【解决方案1】:

是的,有。在这里你可以看到完整的例子:

using System;
using System.Data.Entity;

namespace ConsoleApplication1
{
    class MyDbContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Properties().Configure(c =>
            {
                var name = c.ClrPropertyInfo.Name;
                var newName = char.ToLower(name[0]) + name.Substring(1);
                c.HasColumnName(newName);
            });
        }

        public MyDbCondenxt(string cs) : base(cs)
        {

        }

        public DbSet<MyModel> MyModels { get; set; }

    }

    class Program
    {
        static void Main(string[] args)
        {
            var context = new MyDbContext ("DefaultConnection");
            context.MyModels.Add(new MyModel{SomeText = "hello"});
            context.SaveChanges();

            Console.ReadLine();
        }
    }

    class MyModel
    {
        public int Id { get; set; }
        public string SomeText { get; set; }
    }


}

属性名称为“SomeText”,列名称为“someText”。

【讨论】:

【解决方案2】:

我不知道解决方案级别,但您可以在实体上设置属性

[Table("myEntity")]
public class MyEntity{}

【讨论】:

  • 谢谢,虽然我正在寻找会影响整个模型的东西,因为遍历每个类的整个属性集有点麻烦。
【解决方案3】:

实现这一目标并非不可能,但也绝非易事。其中一些取决于您正在使用哪种类型的 ef 模型,代码优先或数据库/模型优先(它们在这方面相似),或者您是否使用旧的基于 ObjectContext 的方法。

一般来说,EF 使用 T4 模板在除代码之外的所有内容中创建实际的类和模型,因此可以编辑 T4 模板并生成您想要的任何内容,例如使用 PascalCasing 自动生成属性。

如果您首先使用代码(实际上并不要求您首先编写代码,这是一个糟糕的名称),那么您可以使用 Entity Framework 强大工具对您的数据库进行逆向工程以首先编写模型,然后它再次使用T4 执行此操作。

如果您首先使用实际代码(即创建模型并从模型生成数据库),那么在现有的 EF5 或更低版本中可能无法实现。 EF6(目前处于 alpha 阶段)有一些称为自定义约定的东西,您可能会使用它,但距离生产质量还有很长的路要走。

【讨论】:

    【解决方案4】:

    之前我也遇到过这种问题。所以我简单地用c#写了一个工具来重命名现有的edmx文件,然后在重命名edmx文件的每个部分之后,接下来使用T4模板重新生成Poco类。它解决了我的问题。它生成具有 Camel Case 属性的预期 POCO 类。基本上在 edmx 中我们有 3 层。所以我们需要修改它们的2层。

    • 映射部分
    • 概念模型部分

    请找到以下课程来做到这一点。

    namespace Edmx_Manager_V1._0
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Xml;
    
        public static class RenameManager
        {
            public static XmlDocument Document = new XmlDocument();
            public static string FilePath;
            public static XmlNamespaceManager nsmgr;
    
            /// <summary>
            /// Updates the conceptual models section.
            /// </summary>
            public static void UpdateConceptualModelsSection()
            {
    
                ///////////////////////update ConceptualModels section//////////////////////////////////////////////////////////
    
                XmlNodeList Schema = Document.SelectNodes("/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema", nsmgr);
    
                XmlNode SchemaNode = Schema[0];
                XmlElement SchemaNodeXmlElement = SchemaNode as XmlElement;
    
                //get all EntitySet nodes under  EntityContainer node
                XmlNodeList EntitySetlist = SchemaNodeXmlElement.GetElementsByTagName("EntitySet");
    
                //get all EntityType nodes under  SchemaNode
                XmlNodeList EntityTypelist = SchemaNodeXmlElement.GetElementsByTagName("EntityType");
    
                foreach (XmlNode EntityTypenode in EntityTypelist)
                {
    
                    //to call GetElementsByTagName we need XmlElement object
                    XmlElement EntityTypenodeelement = EntityTypenode as XmlElement;
    
                    //get all PropertyRef nodes under  EntityType node
                    XmlNodeList PropertyReflist = EntityTypenodeelement.GetElementsByTagName("PropertyRef");
    
                    foreach (XmlNode PropertyRefnode in PropertyReflist)
                    {
                        //update name attribute of Key/PropertyRef nodes
                        XmlAttribute PropertyRef_nameAttribute = PropertyRefnode.Attributes["Name"];
                        PropertyRef_nameAttribute.Value = UppercaseFirst(PropertyRef_nameAttribute.Value);
                    }
    
                    //get all Property nodes under  EntityType node
                    XmlNodeList Propertylist = EntityTypenodeelement.GetElementsByTagName("Property");
    
                    foreach (XmlNode Propertynode in Propertylist)
                    {
                        //update name attribute of PropertyRef nodes
                        XmlAttribute Property_nameAttribute = Propertynode.Attributes["Name"];
                        Property_nameAttribute.Value = UppercaseFirst(Property_nameAttribute.Value);
                    }
    
                    //get all NavigationProperty nodes under  EntityType node
                    XmlNodeList NavigationPropertylist = EntityTypenodeelement.GetElementsByTagName("NavigationProperty");
    
                    foreach (XmlNode NavigationPropertynode in NavigationPropertylist)
                    {
                        //update name attribute of NavigationProperty nodes
                        XmlAttribute NavigationPropertynode_nameAttribute = NavigationPropertynode.Attributes["Name"];
                        NavigationPropertynode_nameAttribute.Value = UppercaseFirst(NavigationPropertynode_nameAttribute.Value) + "s";// we append "s" for nav properties
                    }
                }
    
                //get  Association node under  Schema node
                XmlNodeList Associationlist = SchemaNodeXmlElement.GetElementsByTagName("Association");
    
                //get all Association nodes and process
                foreach (XmlNode AssociationNode in Associationlist)
                {
                    if (AssociationNode != null)
                    {
                        XmlElement AssociationNodeXmlElement = AssociationNode as XmlElement;
                        //get all end nodes under Association
                        XmlNodeList EndNodelist2 = AssociationNodeXmlElement.GetElementsByTagName("End");
    
                        //get all PropertyRef nodes under Association
                        XmlNodeList PropertyReflist2 = AssociationNodeXmlElement.GetElementsByTagName("PropertyRef");
    
                        foreach (XmlNode PropertyRefNode2 in PropertyReflist2)
                        {
                            //update Type attribute
                            XmlAttribute PropertyRefNode2Attribute = PropertyRefNode2.Attributes["Name"];
                            PropertyRefNode2Attribute.Value = UppercaseFirst(PropertyRefNode2Attribute.Value);
                        }
                    }
                }
    
                Console.WriteLine("ConceptualModelSection updated..");
            }
    
            /// <summary>
            /// Updates the mappings section.
            /// </summary>
            public static void UpdateMappingsSection()
            {
    
                ///////////////////////update edmx:Mappings section//////////////////////////////////////////////////////////
    
                XmlNodeList EntityContainerMapping = Document.SelectNodes("/edmx:Edmx/edmx:Runtime/edmx:Mappings/cs:Mapping", nsmgr);
                XmlNode EntityContainerMapping_Node = EntityContainerMapping[0];
                XmlElement EntityContainerMappingNode_XmlElement = EntityContainerMapping_Node as XmlElement;
    
                // update name attribute of all EntitySetMapping nodes
    
                //get all EntitySetMapping nodes
                XmlNodeList EntitySetMappinglist = EntityContainerMappingNode_XmlElement.GetElementsByTagName("EntitySetMapping");
    
                //get all EntityTypeMapping nodes
                XmlNodeList EntityTypeMappinglist = EntityContainerMappingNode_XmlElement.GetElementsByTagName("EntityTypeMapping");
    
                //get all ScalarProperty nodes
                XmlNodeList ScalarPropertyist = EntityContainerMappingNode_XmlElement.GetElementsByTagName("ScalarProperty");
    
                foreach (XmlNode ScalarPropertyNode in ScalarPropertyist)
                {
                    XmlAttribute nameAttribute = ScalarPropertyNode.Attributes["Name"];
                    nameAttribute.Value = UppercaseFirst(nameAttribute.Value);
                }
    
                Console.WriteLine("MappingSection updated..");
            }
    
            /// <summary>
            /// Uppercases the first.
            /// </summary>
            /// <param name="name">The name.</param>
            /// <returns></returns>
            private static string UppercaseFirst(string name)
            {
    
                return char.ToUpper(name[0]) + name.Substring(1);
    
            }
        }
    }
    

    用法:

                RenameManager.FilePath = @"C:\Users\therath\testApp\Model1.edmx";
                // Path of edmx file in the your solution
                RenameManager.Document.Load(@RenameManager.FilePath);
                RenameManager.nsmgr = new XmlNamespaceManager(RenameManager.Document.NameTable);
                RenameManager.nsmgr.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");
                RenameManager.nsmgr.AddNamespace("edm", "http://schemas.microsoft.com/ado/2008/09/edm");
                //nsmgr.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");
                RenameManager.nsmgr.AddNamespace("cs", "http://schemas.microsoft.com/ado/2008/09/mapping/cs");
    
                try
                {
                    RenameManager.UpdateConceptualModelsSection();
                    RenameManager.UpdateMappingsSection();
                    RenameManager.Document.Save(@RenameManager.FilePath);
                }
    
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
    

    如果您再次生成 edmx,您可能需要再次运行此工具。

    【讨论】:

      【解决方案5】:

      有一些方法可以做到这一点,其中一些已经被其他人指出..

      我找到了一个可以做到这一点的课程......

      namespace System.Data.Entity.ModelConfiguration.Conventions
      {
        /// <summary>
       /// Convention to convert any data types that were explicitly specified, via data     annotations or <see cref="T:System.Data.Entity.DbModelBuilder"/> API,
       ///                 to be lower case. The default SqlClient provider is case   sensitive and requires data types to be lower case. This convention 
      ///                 allows the <see   cref="T:System.ComponentModel.DataAnnotations.ColumnAttrbiute"/> and <see cref="T:System.Data.Entity.DbModelBuilder"/> API to be case insensitive.
      /// 
      /// </summary>
      public sealed class ColumnTypeCasingConvention : IDbConvention<DbTableColumnMetadata>,   IConvention
      {
        internal ColumnTypeCasingConvention()
      {
      }
      
      [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")]
      void IDbConvention<DbTableColumnMetadata>.Apply(DbTableColumnMetadata tableColumn, DbDatabaseMetadata database)
      {
        if (string.IsNullOrWhiteSpace(tableColumn.TypeName))
          return;
        tableColumn.TypeName = tableColumn.TypeName.ToLowerInvariant();
      }
      

      } }

      idbconvertion 的显式实现做了你可以实现的事情

      另一个是

      转到解决方案 => 并找到文件夹 obj/debug/edmxresourcestoembed

      共有三个文件 db.csdl , db.msl , db.ssdl 编辑 msl 文件 => 你会看到每个表的映射,如下所示。

       <EntitySetMapping Name="Address">
        <EntityTypeMapping TypeName="IsTypeOf(AdventureWorksLTModel.Address)">
          <MappingFragment StoreEntitySet="Address">
            <ScalarProperty Name="AddressID" ColumnName="AddressID" />
            <ScalarProperty Name="AddressLine1" ColumnName="AddressLine1" />
            <ScalarProperty Name="AddressLine2" ColumnName="AddressLine2" />
            <ScalarProperty Name="City" ColumnName="City" />
            <ScalarProperty Name="StateProvince" ColumnName="StateProvince" />
            <ScalarProperty Name="CountryRegion" ColumnName="CountryRegion" />
            <ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
            <ScalarProperty Name="rowguid" ColumnName="rowguid" />
            <ScalarProperty Name="ModifiedDate" ColumnName="ModifiedDate" />
          </MappingFragment>
        </EntityTypeMapping>
      </EntitySetMapping>
      

      【讨论】:

        【解决方案6】:

        您可以在 .edmx 文件中更改它。只需单击属性名称并将其重命名为驼峰式大小写,每当您尝试使用该对象访问它时都会反映相同的情况。

        【讨论】:

        • 谢谢,虽然我正在寻找会影响整个模型的东西,因为遍历每个类的整个属性集有点麻烦。
        【解决方案7】:

        您可以使用外部工具,例如 http://www.devart.com/entitydeveloper/

        使用内置 EDMX 设计器这是不可能的,因为“从数据库更新”例程没有这样的功能。

        【讨论】:

          【解决方案8】:

          类代码是从 T4 模板生成的。根据您的配置,这可能已经在您的项目中,或者 EDMX 可能正在使用内置的,在这种情况下,您需要添加自己的并在 EDMX 中将“代码生成策略”设置为“无”属性(通过模型浏览器)。从这个文件中很容易找到和修改类和属性名称的生成。

          默认调用Escape函数,该函数定义在Visual Studio文件夹下"IDE/Extensions/Microsoft/Entity Framework Tools/Templates/Includes"的包含文件中,最终只需致电CreateEscapedIdentifier。只需使用字符串的大写版本调用它即可。

          仅供参考:这些名称来自 EDMX 中定义的 EntityTypeNavigationProperty 对象,而不是直接来自数据库。如果您使用 EDMX 的“从数据库生成”功能,则名称可能已经经过转换,并且原始表名称不会保留在模型中。不过,这可能不会成为问题。

          【讨论】:

            【解决方案9】:

            实际上,您可以在 edmx 中编辑名称,但每次从数据库刷新时,它都会重新进行。

            使用 edmx 类型数据类型时唯一可行的方法是在数据库的表中使用正确的名称(大写字母),否则会很乏味。

            您当然可以使用指向 sql 的链接,在这种情况下,您可以定义数据类并只提供一个名称属性。但请注意,这种方法明显更加手动,并且在大多数地方都被放弃了,因为它需要更多的思考来设置 edmx 自动生成,这是一种点击、点击、下一个方法。

            所以是的,您可以在 edmx 中编辑名称,但考虑放弃您的 camelCasing 来代替表格,以向 edmx 致敬,这可以为您节省大量工作作为回报,或者您的 .net 自动生成的代理类看起来很奇怪,因为你知道的。

            【讨论】:

              猜你喜欢
              • 2017-09-17
              • 2013-05-16
              • 1970-01-01
              • 2018-01-20
              • 1970-01-01
              • 1970-01-01
              • 2013-09-01
              • 1970-01-01
              • 2013-01-29
              相关资源
              最近更新 更多