數據庫中的屬性全部爲小寫,並且使用下劃線進行單詞分隔。例如: -實體框架POCO實體模板:格式屬性名稱
customer_order_id
我想要的屬性名符合我的PropertyNameCodingConvention,即:customer_order_id -> CustomerOrderId
我已經改變了T4模板來完成這一點,但我很好奇,如果有已經上市的解決方案。
數據庫中的屬性全部爲小寫,並且使用下劃線進行單詞分隔。例如: -實體框架POCO實體模板:格式屬性名稱
customer_order_id
我想要的屬性名符合我的PropertyNameCodingConvention,即:customer_order_id -> CustomerOrderId
我已經改變了T4模板來完成這一點,但我很好奇,如果有已經上市的解決方案。
這需要改變的模板,但這裏是我是如何做的:
添加到EntityPoco.tt(最後收盤前右「#>」標記)的結尾:
private string N(string input) {
return System.Text.RegularExpressions.Regex.Replace(input,
"(?:_|^)([a-z])",
match => match.Groups[1].Value.ToUpper()).Replace("_", "");
}
將所有輸出屬性名稱的地方(總共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("_", "");
}
#>
需要注意的是,如果使用POCO對象將屬性映射到實體(在概念模型中),則根據屬性名稱進行映射,因此_just_更改屬性名稱將不起作用。您還需要更改概念模型實體屬性名稱或使用屬性指定映射(POCO->實體)或更改概念模型(CSL)中的屬性名稱 –
在EDMX文件,你有兩個不同的模式,和一個映射架構。你可以做的是,你可以修改概念模式並更改屬性名稱,但是刷新EDMX可能會擦除這些信息。但通過這樣做,您根本不必更改模板。
您是對的,這是一個選項,但它有幾個明顯的缺點:1.您對於清爽的EDM是正確的。 2.手動更改名稱並不好玩。 3.我不能使用正則表達式(不在VS中)更改名稱。 –
只是好奇你有沒有看過自定義約定來完成這個? http://blogs.msdn.com/b/adonet/archive/2011/01/10/ef-feature-ctp5-pluggable-conventions.aspx –
是的,我的理解是適用於CodeFirst方法的,這與Code我正在做,即我有數據庫,並需要生成C#代碼(所以這是'代碼最後'的方法)。 –