首先在实体框架模型中为生成的代码添加文档

时间:2012-12-18 10:40:59

标签: entity-framework visual-studio-2012 code-generation ef-model-first

自VS 2010以来,我一直在使用Entity Framework模型。当我构建项目时,EF会生成一个包含所有实体的Model.Designer.cs文件。此设计器文件还包含添加到EDMX文件中的实体的文档。

当我在VS 2012中创建新的EF模型第一个项目时,Model.tt文件被添加到我的EDMX文件中。此T4模板为模型中的每个实体生成单个文件。遗憾的是,EDMX文件中的文档未在生成的代码中使用。

我非常喜欢记录我的模型,因此IntelliSense在使用时会显示出来。到目前为止我找到的唯一解决方法是删除Model.tt和生成的类文件,然后重新启动我的EDMX文件上的代码生成。这将恢复到我在VS 2010中使用的行为。但是,我希望每个实体都有一个单独的文件。

有没有办法(最好使用VS工具而不必修改VS附带的任何文件)在生成的单个类文件中包含EDMX文件中的文档?

编辑:为了进一步说明我的问题,这是一个简单的例子。

假设我的模型如下:simple entity framework model

我在Id属性的“属性”窗口中突出显示了我输入文档的部分。

这就是EDMX文件中实体的样子:

    <EntityType Name="Entity1">
      <Key>
        <PropertyRef Name="Id" />
      </Key>
      <Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" >
        <Documentation>
          <Summary>This is documentation for the ID property.</Summary>
        </Documentation>
      </Property>
    </EntityType>

Model.tt生成的类(Entity1.cs)如下所示:

public partial class Entity1
{
    public int Id { get; set; }
}

但是当我为我的模型打开代码生成时,这就是实体在Model.Designer.cs中的样子:

/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmEntityTypeAttribute(NamespaceName="Model1", Name="Entity1")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Entity1 : EntityObject
{
    #region Factory Method

    /// <summary>
    /// Create a new Entity1 object.
    /// </summary>
    /// <param name="id">Initial value of the Id property.</param>
    public static Entity1 CreateEntity1(global::System.Int32 id)
    {
        Entity1 entity1 = new Entity1();
        entity1.Id = id;
        return entity1;
    }

    #endregion

    #region Simple Properties

    /// <summary>
    /// This is documentation for the ID property.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Int32 Id
    {
        get
        {
            return _Id;
        }
        set
        {
            if (_Id != value)
            {
                OnIdChanging(value);
                ReportPropertyChanging("Id");
                _Id = StructuralObject.SetValidValue(value, "Id");
                ReportPropertyChanged("Id");
                OnIdChanged();
            }
        }
    }
    private global::System.Int32 _Id;
    partial void OnIdChanging(global::System.Int32 value);
    partial void OnIdChanged();

    #endregion

}

所以你看到:Model.Designer.cs包含我的自定义文档字符串“这是ID属性的文档。”虽然Entity1.cs没有。但是,如果有很多实体,并且调试到这个文件有点慢,Model.Designer.cs会变得很大。我更喜欢有几个小文件(每个实体一个),但仍然在生成的代码中保留EDMX文件中的文档。

1 个答案:

答案 0 :(得分:13)

我认为您必须修改T4文件。我遇到了同样的问题,并仔细阅读了T4文件,并尝试按照此处的说明进行操作:http://karlz.net/blog/index.php/2010/01/16/xml-comments-for-entity-framework/

但是,我们正在使用VS 2012并且该指令似乎不能100%运行。我最终更改了T4文件末尾的属性生成代码,它的工作原理与我想要的完全相同。更改位于CodeStringGenerator.Property()和CodeStringGenerator.NavigationProperty()

public string Property(EdmProperty edmProperty)
{
    string doc = "";
    if (edmProperty.Documentation != null)
    {
        doc = string.Format(
        CultureInfo.InvariantCulture,
        "\n\t\t/// <summary>\n\t\t/// {0} - {1}\n\t\t/// </summary>\n\t\t",
        edmProperty.Documentation.Summary ?? "",
        edmProperty.Documentation.LongDescription ?? "");
    }

    return doc + string.Format(
        CultureInfo.InvariantCulture,
        "{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)));
}

public string NavigationProperty(NavigationProperty navigationProperty)
{
    var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
    string doc = "";
    if (navigationProperty.Documentation != null)
    {
        doc = string.Format(
        CultureInfo.InvariantCulture,
        "\n\t\t/// <summary>\n\t\t/// {0} - {1}\n\t\t/// </summary>\n\t\t",
        navigationProperty.Documentation.Summary ?? "",
        navigationProperty.Documentation.LongDescription ?? "");
    }

    return doc + string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
        navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
        _code.Escape(navigationProperty),
        _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
}

请注意,它不适用于类文档,因此您必须使用实体和复杂类型执行此类操作

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