Шаблон сущности POCO Entity Framework: имена свойств формата - PullRequest
4 голосов
/ 01 декабря 2011

свойств в базе данных все в маленьком регистре и используют подчеркивание для разделения слов. E.g.:

customer_order_id

Я хочу, чтобы имена свойств соответствовали моей PropertyNameCodingConvention, т.е. customer_order_id -> CustomerOrderId

Я изменил шаблон T4 для достижения этой цели, но мне любопытно, есть ли уже доступное решение.

Ответы [ 2 ]

1 голос
/ 01 декабря 2011

В файле EDMX у вас есть две разные схемы и одна схема сопоставления.Что вы можете сделать, так это то, что вы можете изменить концептуальную схему и изменить имена свойств, однако обновление EDMX может стереть эту информацию.Но при этом вам вообще не придется менять шаблон.

0 голосов
/ 01 декабря 2011

Это требует изменения шаблона, но вот как я это сделал:

  1. Добавьте в конец EntityPoco.tt (прямо перед последним закрывающим тегом '#>'):

    private string N(string input) {
        return System.Text.RegularExpressions.Regex.Replace(input, 
            "(?:_|^)([a-z])", 
            match => match.Groups[1].Value.ToUpper()).Replace("_", "");
    }
    
  2. Оберните все места, где выводится имя свойства (всего 6, см. Код ниже).

Вотполный текст:

<#
//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#>
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
 output extension=".cs"#><#

CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"PSI.Entities.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
WriteHeader(fileManager);

foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
    fileManager.StartNewFile(entity.Name + ".cs");
    BeginNamespace(namespaceName, code);
#>
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
{
<#
    var propertiesWithDefaultValues = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && p.DefaultValue != null);
    var collectionNavigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
    var complexProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity);

    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
    {
#>
    public <#=code.Escape(entity)#>()
    {
<#
        foreach (var edmProperty in propertiesWithDefaultValues)
        {
#>
        this.<#=N(code.Escape(edmProperty))#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
<#
        }

        foreach (var navigationProperty in collectionNavigationProperties)
        {
#>
        this.<#=N(code.Escape(navigationProperty))#> = new HashSet<<#=code.Escape(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
        }

        foreach (var complexProperty in complexProperties)
        {
#>
        this.<#=N(code.Escape(complexProperty))#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
<#
        }
#>
    }

<#
    }

    var primitiveProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity);
    if (primitiveProperties.Any())
    {
        foreach (var edmProperty in primitiveProperties)
        {
            WriteProperty(code, edmProperty);
        }
    }

    if (complexProperties.Any())
    {
#>

<#
        foreach(var complexProperty in complexProperties)
        {
            WriteProperty(code, complexProperty);
        }
    }

    var navigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity);
    if (navigationProperties.Any())
    {
#>

<#
        foreach (var navigationProperty in navigationProperties)
        {
            WriteNavigationProperty(code, navigationProperty);
        }
    }
#>
}

<#
    EndNamespace(namespaceName);
}

foreach (var complex in ItemCollection.GetItems<ComplexType>().OrderBy(e => e.Name))
{
    fileManager.StartNewFile(complex.Name + ".cs");
    BeginNamespace(namespaceName, code);
#>
<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
{
<#
    var complexProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == complex);
    var propertiesWithDefaultValues = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex && p.DefaultValue != null);

    if (propertiesWithDefaultValues.Any() || complexProperties.Any())
    {
#>
    public <#=code.Escape(complex)#>()
    {
<#
        foreach (var edmProperty in propertiesWithDefaultValues)
        {
#>
        this.<#=N(code.Escape(edmProperty))#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
<#
        }

        foreach (var complexProperty in complexProperties)
        {
#>
        this.<#=N(code.Escape(complexProperty))#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
<#
        }
#>
    }

<#
    }

    var primitiveProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex);
    if (primitiveProperties.Any())
    {
        foreach(var edmProperty in primitiveProperties)
        {
            WriteProperty(code, edmProperty);
        }
    }

    if (complexProperties.Any())
    {
#>

<#
        foreach(var edmProperty in complexProperties)
        {
            WriteProperty(code, edmProperty);
        }
    }
#>
}

<#
    EndNamespace(namespaceName);
}

if (!VerifyTypesAreCaseInsensitiveUnique(ItemCollection))
{
    return "";
}

fileManager.Process();

#>
<#+
void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
{
    fileManager.StartHeader();
#>
//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;

<#+
    fileManager.EndBlock();
}

void BeginNamespace(string namespaceName, CodeGenerationTools code)
{
    CodeRegion region = new CodeRegion(this);
    if (!String.IsNullOrEmpty(namespaceName))
    {
#>
namespace <#=code.EscapeNamespace(namespaceName)#>
{
<#+
        PushIndent(CodeRegion.GetIndent(1));
    }
}


void EndNamespace(string namespaceName)
{
    if (!String.IsNullOrEmpty(namespaceName))
    {
        PopIndent();
#>
}
<#+
    }
}

void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
{
    WriteProperty(Accessibility.ForProperty(edmProperty),
                  code.Escape(edmProperty.TypeUsage),
                  code.Escape(edmProperty),
                  code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                  code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

void WriteNavigationProperty(CodeGenerationTools code, NavigationProperty navigationProperty)
{
    var endType = code.Escape(navigationProperty.ToEndMember.GetEntityType());
    WriteProperty(PropertyVirtualModifier(Accessibility.ForProperty(navigationProperty)),
                  navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
                  code.Escape(navigationProperty),
                  code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
                  code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
}

void WriteProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
{
#>
    <#=accessibility#> <#=type#> <#=N(name)#> { <#=getterAccessibility#>get; <#=setterAccessibility#>set; }
<#+
}

string PropertyVirtualModifier(string accessibility)
{
    return accessibility + (accessibility != "private" ? " virtual" : "");
}

bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
{
    var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
    foreach(var type in itemCollection.GetItems<StructuralType>())
    {
        if (!(type is EntityType || type is ComplexType))
        {
            continue;
        }

        if (alreadySeen.ContainsKey(type.FullName))
        {
            Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
            return false;
        }
        else
        {
            alreadySeen.Add(type.FullName, true);
        }
    }

    return true;
}

private string N(string input) {
    return System.Text.RegularExpressions.Regex.Replace(input, "(?:_|^)([a-z])", match => match.Groups[1].Value.ToUpper()).Replace("_", "");
}
#>
...