2013-12-11 54 views
2

我对我的EDMX文件有以下问题。EntityFramework t4模板 - XML文档

其中我已经为属性和实体编写了一些文档,但EF 5的t4模板并没有生成这些值。

我想要的结果应该是

public class Person 
{ 
    /// <summary> 
    /// Hello World Summary!! 
    /// </summary> 
    /// <remarks> 
    /// Hello World Remarks!! 
    /// </remarks> 
    public string Name { get; set; } 
} 

但我只得到

public class Person 
{ 
    public string Name { get; set; } 
} 

如果不是这个,为什么我还能够在EDMX文件中设置文档属性。

回答

9

它看起来实体框架不会为您生成代码文档的对象,我不能在nuget上看到一个解决方案,这是一个耻辱。

您可以修改T4模板,为您做到这一点没有太多的麻烦。让你开始,如果你打开T4模板的实体,并发现看起来像这样(约行74对我来说)行:

<#=codeStringGenerator.Property(edmProperty)#> 

然后改变它的东西是这样的:

<# if (edmProperty != null && edmProperty.Documentation != null) {#> 
/// <summary> 
/// <#= edmProperty.Documentation.Summary #> 
/// </summary> 
/// <remarks> 
/// <#= edmProperty.Documentation.LongDescription #> 
/// </remarks> 
<# } #> 
    <#=codeStringGenerator.Property(edmProperty)#> 

这将生成您的属性的文档。

而且也如果你去,看起来像这样(约行28对我来说)行:

<#=codeStringGenerator.EntityClassOpening(entity)#> 

然后改变它的东西是这样的:

<# if (entity != null && entity.Documentation != null) {#> 
/// <summary> 
/// <#= entity.Documentation.Summary #> 
/// </summary> 
/// <remarks> 
/// <#= entity.Documentation.LongDescription #> 
/// </remarks> 
<# } #> 
<#=codeStringGenerator.EntityClassOpening(entity)#> 

这应该给你你的班级文件。

可能还有其他一些需要更新的地方(比如复杂和导航属性),但它应该可以让你获得最大的方式。

Matt

+0

谢谢,非常有帮助!有关处理文档中换行符的最佳方法的任何建议?使用上面的方法,评论(///)不会在Summary \ LongDescription – mutex

+2

中为每个换行重复实际执行如下操作:edmProperty.Documentation.Summary.Replace(“\ n”,“\ r \ n \ t // /“)可以做到这一点,还有额外的好处,它可以防止视觉工作室关于行尾的恼人警告不一致。 – mutex

1

这是我对此的看法。

在你.TT文件生成的CodeStringGenerator类,我添加了这个方法:

private string Comments(EdmMember member) 
{ 
    string comments = member.Documentation != null 
     ? (string.IsNullOrEmpty(member.Documentation.Summary) 
      ? "" 
      : @" 
/// <summary> 
/// " + member.Documentation.Summary.Replace("\n", Environment.NewLine + " /// ") + @" 
/// </summary> 
") 
      + 
      (string.IsNullOrEmpty(member.Documentation.LongDescription) 
      ? "" 
      : @"/// <remarks> 
/// " + member.Documentation.LongDescription.Replace("\n", Environment.NewLine + " /// ") + @" 
/// </remarks> 
") 
     : ""; 
    return comments; 
} 

我承认这种方法有两个问题:1)它假定缩进的一定水平,虽然这是预期b)如果没有摘要,则在评论前添加一行额外的行。但这不太可能发生。

然后,我打电话从生成简单和导航性能的方法,这个方法:

public string Property(EdmProperty edmProperty) 
{ 
    string comments = Comments(edmProperty); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     @"{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     Accessibility.ForProperty(edmProperty), 
     _typeMapper.GetTypeName(edmProperty.TypeUsage), 
     _code.Escape(edmProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(edmProperty)), 
     comments); 
} 

public string NavigationProperty(NavigationProperty navProp) 
{ 
    string comments = Comments(navProp); 
    var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5}{0} {1} {2} {{ {3}get; {4}set; }}", 
     AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), 
     navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 
     _code.Escape(navProp), 
     _code.SpaceAfter(Accessibility.ForGetter(navProp)), 
     _code.SpaceAfter(Accessibility.ForSetter(navProp)), 
     comments); 
} 
0

我想,因为,因为我目前的项目配置的详细信息添加到马特Mhetton的回答(CA和风格警察)一切都必须记录..

一方面,你必须在设计中添加文档属性要记录(类,简单性,复杂性和导航性能)

在你要打开WhateverModel另一方面应有尽有。 TT你havecreated和编辑,使其包含的文件,我将解释一步一步来:

1.-对于类文档,寻找:

<#=codeStringGenerator.UsingDirectives(inHeader: false)#> 
<#=codeStringGenerator.EntityClassOpening(entity)#> 

(在我的情况下,第26行),把你的意见只是那些两条线这样间:

<#=codeStringGenerator.UsingDirectives(inHeader: false)#> 
<# if (entity != null && entity.Documentation != null) {#> 
/// <summary> 
/// <#= entity.Documentation.Summary #> 
/// </summary> 
<# } #> 
<#=codeStringGenerator.EntityClassOpening(entity)#> 

2:对于构造文档public <#=code.Escape(entity)#>() thaqt就是生成的构造函数,因此把你的文件只是在此之前,像这样一行:

<# if (entity != null && entity.Documentation != null) {#> 
    /// <summary> 
    /// <#= entity.Documentation.Summary #> 
    /// </summary> 
<# } #> 
    public <#=code.Escape(entity)#>() 
    { 

3.-为了证明每个属性foreach (var edmProperty in simpleProperties),这看起来是一个将生成的属性代码,因此,它应该是这样的:

foreach (var edmProperty in simpleProperties) 
     { 
#> 
<# if (edmProperty != null && edmProperty.Documentation != null) {#>  
    /// <summary> 
    /// <#= edmProperty.Documentation.Summary #> 
    /// </summary> 
<# } #> 
    <#=codeStringGenerator.Property(edmProperty)#> 
<# 

     } 

(注:这是简单的性质,但要BE3复杂性以同样的方式...)

4.-对于导航属性一模一样,寻找foreach (var navigationProperty in navigationProperties)并添加你的文档是这样的:

foreach (var navigationProperty in navigationProperties) 
     { 
#> 
<# if (navigationProperty != null && navigationProperty.Documentation != null) {#> 
    /// <summary> 
    /// <#= navigationProperty.Documentation.Summary #> 
    /// </summary> 
<# } #> 
    <#=codeStringGenerator.NavigationProperty(navigationProperty)#> 
<# 

     } 

4.-最后但并非最不重要的,如果你还需要在你的上下文类文档你可以使用这个(寻找<# if (code.Escape(container) != null) {#>):

<# if (code.Escape(container) != null) {#> 
/// <summary> 
/// Represents <#= code.Escape(container) #> 
/// </summary> 
<# } #> 
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext 
{ 

<# if (code.Escape(container) != null) {#> 
    /// <summary> 
    /// Initializes a new instance of the <see cref="<#= code.Escape(container) #>"/> class. 
    /// </summary> 
<# } #> 
    public <#=code.Escape(container)#>() 
    : base("name=<#=container.Name#>") 
    { 
<# 
if (!loader.IsLazyLoadingEnabled(container)) 
{ 
#> 
     this.Configuration.LazyLoadingEnabled = false; 
<# 
} 
#> 
    } 

    /// <summary> 
    /// On Model Creating 
    /// </summary> 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     throw new UnintentionalCodeFirstException(); 
    } 

<# 
    foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>()) 
    { 
#> 

    <# if (code.Escape(entitySet) != null) {#> 
    /// <summary> 
    /// Gets or sets the <#=code.Escape(entitySet)#> 
    /// </summary> 
    <# } #> 

我希望它能帮助像Matt Whetton的回答帮助我(谢谢Matt)。