实体框架 - 将第一个属性名称字母大写

时间:2011-06-28 10:33:55

标签: c# .net sql entity-framework

通常,我倾向于使用以下驼峰大小写约定我的sql数据库列:

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

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

CamelCase(注意第一个是在uppwer的情况下)。

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

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

9 个答案:

答案 0 :(得分:14)

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

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”。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

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

通常,EF使用T4模板来创建除了代码之外的所有类和模型,因此可以编辑T4模板并生成任何所需的内容,例如使用PascalCasing自动生成属性。

如果您首先使用代码(实际上并不需要您首先编码,这是一个可怕的名称),那么您可以使用实体框架电源工具对数据库进行反向工程以对第一个模型进行编码,并再次使用T4这样做。

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

答案 3 :(得分:1)

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

  • MappingsSection
  • ConceptualModelsSection

请找到以下课程。

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,则可能需要再次运行此工具。

答案 4 :(得分:1)

有办法做到这一点,有些已经被其他人指出..

我找到了一个这样做的课......

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的显式实现可以实现你可以实现的东西

另一个是

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

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

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

答案 5 :(得分:0)

您可以在.edmx文件中更改它。只需单击属性名称并将其重命名为camel case,只要您尝试使用该对象访问它,就会反映出来。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

默认是调用Escape函数,该函数在Visual Studio文件夹下“IDE / Extensions / Microsoft / Entity Framework Tools / Templates / Includes”的包含文件中定义,最后只需拨打CreateEscapedIdentifier。只需使用字符串的大写版本调用它。

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

答案 8 :(得分:0)

您可以实际编辑edmx中的名称,但每次从数据库刷新时,它都会再次执行此操作。

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

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

所以是的,你可以编辑edmx中的名字,但是考虑放弃你的camelCasing代替表格,与edmx相同,这可以节省你的工作量,或者.net自动生成的代理类看起来很奇怪,如你知道吗。