如何使用 Oracle 的实体框架支持强制帕斯卡案例?

Posted

技术标签:

【中文标题】如何使用 Oracle 的实体框架支持强制帕斯卡案例?【英文标题】:How to force pascal case with Oracle's Entity Framework support? 【发布时间】:2012-05-22 01:22:53 【问题描述】:

Oracle 的实体框架支持使所有类名大写并保留下划线。 所以 ORDER_ITEMS 表在类名中变为 ORDER_ITEMS。但我想对类名使用 Pascal 大小写。

ORDER_ITEMS ==> 需要 OrderItems。

如何更改默认命名规则?

【问题讨论】:

【参考方案1】:

大约 2 周前,我的任务是摆脱 Linq Connect 作为我们的数据提供者,将 EF 用于我们的 ORM 操作。好吧,众所周知,当微软和甲骨文参与其中时,事情从来都不是一件容易的事,因为它们不能很好地合作。精明的开发人员需要为 Pascal 大小写和复数找到解决方案,以便从 Oracle 数据库生成的实体符合我们的标准。我们不希望带有下划线的表名出现在我们的模型上。经过一番思考和开发,最终得出了一个好的解决方案。最终结果是操作 EDMX 文件,然后运行 ​​T4 模板以使奇迹发生。我们的最终结果将所有实体及其属性转换为 Pascal 套管。它还将所有存储函数转换为 Pascal 大小写。集合的导航属性也都是多元化的。以下是要遵循的步骤和代码 sn-p。希望这对编码社区中的某些人有所帮助,您可以随时通过 Twitter 上的 seafarer_007 与我联系,提供有用的 cmets 或建议。这里是: 1. 使用 EF 数据模型项生成 EDMX。我在 Visual Studio 2012 中使用了 EF 5.0。 2. 编写一个控制台应用程序来操作 EDMX 和设计器文件。我在 App Config 中添加了对两者的引用。 3. 应该就是这样,您将拥有 Pascal 大小写和复数实体。您可以随时根据自己的需要调整 Pascal 案例方法。 4. 我在 Visual Studio 2012 和 EF 5.0 上测试了代码。 5. 警告:仅适用于没有点的单字命名空间,基本上你不能为模型使用 OrgName.DeptName.Namespace,它只会处理 OrgName,但是,你可以调整 Pascal 大小写方法来解决这个问题。

控制台应用程序代码如下:

    static void Main(string[] args)
    

        string pathFile = string.Empty;
        string designFile = string.Empty;


        //EDMX File location
        if (ConfigurationManager.AppSettings["EDMX"] != null)
        
            pathFile = ConfigurationManager.AppSettings["EDMX"].ToString();
        

        //Designer location for EF 5.0
        if (ConfigurationManager.AppSettings["EDMXDiagram"] != null)
        
            designFile = ConfigurationManager.AppSettings["EDMXDiagram"].ToString();
        





        XDocument xdoc = XDocument.Load(pathFile);


        const string CSDLNamespace = "http://schemas.microsoft.com/ado/2009/11/edm";
        const string MSLNamespace = "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();



        #region CSDL
        foreach (var entitySet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("EntitySet", CSDLNamespace)))
        
            entitySet.Attribute("Name").Value = PascalCase(entitySet.Attribute("Name").Value);
            entitySet.Attribute("EntityType").Value = PascalCase(entitySet.Attribute("EntityType").Value);
        
        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 = PascalCase(end.Attribute("EntitySet").Value);
            
        

        foreach (var funtionSet in csdl.Element(XName.Get("EntityContainer", CSDLNamespace)).Elements(XName.Get("FunctionImport", CSDLNamespace)))
        

            funtionSet.Attribute("Name").Value = PascalCase(funtionSet.Attribute("Name").Value);

        

        foreach (var entityType in csdl.Elements(XName.Get("EntityType", CSDLNamespace)))
        
            entityType.Attribute("Name").Value = PascalCase(entityType.Attribute("Name").Value);

            foreach (var key in entityType.Elements(XName.Get("Key", CSDLNamespace)))
            
                foreach (var propertyRef in key.Elements(XName.Get("PropertyRef", CSDLNamespace)))
                
                    propertyRef.Attribute("Name").Value = PascalCase(propertyRef.Attribute("Name").Value);
                
            

            foreach (var property in entityType.Elements(XName.Get("Property", CSDLNamespace)))
            
                property.Attribute("Name").Value = PascalCase(property.Attribute("Name").Value);
            

            foreach (var navigationProperty in entityType.Elements(XName.Get("NavigationProperty", CSDLNamespace)))
            
                navigationProperty.Attribute("Name").Value = PascalCase(navigationProperty.Attribute("Name").Value, true, true); 
            

        
        foreach (var association in csdl.Elements(XName.Get("Association", CSDLNamespace)))
        
            foreach (var end in association.Elements(XName.Get("End", CSDLNamespace)))
            
                end.Attribute("Type").Value = PascalCase(end.Attribute("Type").Value);
                           

            foreach(var refs in association.Elements(XName.Get("ReferentialConstraint", CSDLNamespace)))
            

                foreach (var pri in refs.Elements(XName.Get("Principal", CSDLNamespace)))
                

                    foreach (var proref in pri.Elements(XName.Get("PropertyRef", CSDLNamespace)))
                    

                        proref.Attribute("Name").Value = PascalCase(proref.Attribute("Name").Value);
                    

                

                foreach (var pri in refs.Elements(XName.Get("Dependent", CSDLNamespace)))
                

                    foreach (var proref in pri.Elements(XName.Get("PropertyRef", CSDLNamespace)))
                    

                        proref.Attribute("Name").Value = PascalCase(proref.Attribute("Name").Value);
                    

                


            



        
        #endregion

        #region MSL

        foreach (var entitySetMapping in msl.Element(XName.Get("EntityContainerMapping", MSLNamespace)).Elements(XName.Get("EntitySetMapping", MSLNamespace)))
        
            entitySetMapping.Attribute("Name").Value = PascalCase(entitySetMapping.Attribute("Name").Value);

            foreach (var entityTypeMapping in entitySetMapping.Elements(XName.Get("EntityTypeMapping", MSLNamespace)))
            
                entityTypeMapping.Attribute("TypeName").Value = PascalCase(entityTypeMapping.Attribute("TypeName").Value);
                foreach
                (var scalarProperty in
                (entityTypeMapping.Element(XName.Get("MappingFragment", MSLNamespace))).Elements(XName.Get("ScalarProperty", MSLNamespace))
                )
                
                    scalarProperty.Attribute("Name").Value = PascalCase(scalarProperty.Attribute("Name").Value);
                

            
        
        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 = PascalCase(scalarProperty.Attribute("Name").Value);
                
            
        

        foreach (var functionSetMapping in msl.Element(XName.Get("EntityContainerMapping", MSLNamespace)).Elements(XName.Get("FunctionImportMapping", MSLNamespace)))
        
            functionSetMapping.Attribute("FunctionImportName").Value = PascalCase(functionSetMapping.Attribute("FunctionImportName").Value);
        
        #endregion

        xdoc.Save(pathFile);


        XmlDocument designXml = new XmlDocument();

        designXml.Load(designFile);      


        XmlNamespaceManager dsMan = new XmlNamespaceManager(designXml.NameTable);
        dsMan.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2009/11/edmx");
        dsMan.AddNamespace("d", "http://schemas.microsoft.com/ado/2009/11/edmx");


        #region Designer

        XmlNodeList entitySet1 = designXml.DocumentElement.SelectNodes("//d:Diagrams", dsMan);

        foreach (XmlNode xn in entitySet1)
        

            foreach (XmlElement xp in xn.ChildNodes)
            

                foreach (XmlElement z in xp.ChildNodes)
                

                    if (z.Attributes[0].Name == "EntityType")
                    

                        z.Attributes[0].Value = PascalCase(z.Attributes[0].Value.ToString(), true);

                    


                

            


        

        designXml.Save(designFile);


        #endregion

    

    #region Pluralization


    public static string Pluralize(string name)
    

   return System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(new CultureInfo("en-US")).Pluralize(name);
    



    #endregion



    #region Pascal Casing

    public static string PascalCase(StructuralType type, bool sanitizeName = true)
    
        if (type == null)
        
            return null;
        

        return PascalCase(type.Name, sanitizeName);
    


    public static string PascalCase(EdmMember member, bool sanitizeName = true)
    
        if (member == null)
        
            return null;
        

        return PascalCase(member.Name, sanitizeName);
    

    public static string PascalCase(string name, bool sanitizeName = true, bool pluralize = false)
    

       // if pascal case exists
       // exit function

        Regex rgx = new Regex(@"^[A-Z][a-z]+(?:[A-Z][a-z]+)*$");

        string pascalTest = name;

        if (name.Contains("."))
        
            string[] test  = new string[];
            test = name.Split('.');

            if(rgx.IsMatch(test[1].ToString()))
            
                return name;
            

        
        else
        

            if (rgx.IsMatch(name))
            
                return name;
            

        

        //Check for dot notations in namespace

        bool contains = false;
        string[] temp = new string[]  ;
        var namespc = string.Empty;

        if (name.Contains("."))
        
            contains = true;
            temp = name.Split('.');
            namespc = temp[0];

        

        if (contains)
        
            name = temp[1];
        

        name = name.ToLowerInvariant();

        string result = name;
        bool upperCase = false;

        result = string.Empty;
        for (int i = 0; i < name.Length; i++)
        
            if (name[i] == ' ' || name[i] == '_')
            
                upperCase = true;
            
            else
            
                if (i == 0 || upperCase)
                
                    result += name[i].ToString().ToUpperInvariant();
                    upperCase = false;
                
                else
                
                    result += name[i];
                
            
        


        if (contains)
        


            result = namespc.ToString() + "." + result;



        

        if (pluralize)
        
            result = Pluralize(result);
        


        return result;
    
    #endregion

【讨论】:

你提到的这个设计文件路径是什么?【参考方案2】:

目前还没有。 https://forums.oracle.com/forums/thread.jspa?messageID=9681138

【讨论】:

【参考方案3】:

如果它是代码优先的方法,假设您使用任何内联查询只包括命名对象之前和之后的引号转义序列。它将允许。

【讨论】:

以上是关于如何使用 Oracle 的实体框架支持强制帕斯卡案例?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 .Include 查询实体框架 6 强制外部联接

如何强制实体框架始终从数据库中获取更新数据?

如何强制实体框架插入标识列?

实体框架 6.0 和 oracle 11

有人在使用带有 Oracle 数据库的实体框架吗?

如何使用实体框架在 oracle 包中调用存储过程?