3

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

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

我真的很喜欢记录我的模型,以便在使用它时显示 IntelliSense。到目前为止,我发现的唯一解决方法是删除 Model.tt 和生成的类文件,然后重新打开我的 EDMX 文件上的代码生成。这将恢复到我在 VS 2010 中使用的行为。但是,我希望每个实体都有一个单独的文件。

有什么方法(最好使用 VS 工具,而无需修改 VS 附带的任何文件)将 EDMX 文件中的文档包含在生成的单个类文件中?

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

假设我的模型如下所示:简单实体框架模型

我在 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 文件的文档。

4

1 回答 1

14

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

但是,我们使用的是 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)#>
于 2013-01-04T00:49:50.043 回答