3

私は VS 2010 以降、最初に Entity Framework モデルを使用しています。プロジェクトをビルドすると、EF はすべてのエンティティを含む Model.Designer.cs ファイルを生成します。このデザイナー ファイルには、EDMX ファイル内のエンティティに追加されたドキュメントも含まれています。

VS 2012 で新しい EF モデルの最初のプロジェクトを作成すると、Model.tt ファイルが EDMX ファイルに追加されます。この T4 テンプレートは、モデル内のエンティティごとに 1 つのファイルを生成します。残念ながら、EDMX ファイルのドキュメントは、生成されたコードでは使用されません。

モデルを文書化するのが本当に好きなので、使用時に IntelliSense が表示されます。これまでに見つけた唯一の回避策は、Model.tt と生成されたクラス ファイルを削除し、EDMX ファイルのコード生成をオンに戻すことです。これは、VS 2010 から使用されている動作に戻ります。ただし、エンティティごとに個別のファイルを使用することをお勧めします。

生成された単一クラス ファイルに EDMX ファイルのドキュメントを含める方法はありますか (できれば VS ツールを使用し、VS に付属するファイルを変更する必要はありません)。

編集:私の問題をさらに説明するために、ここに簡単な例を示します。

私のモデルが次のようになっているとしましょう:単純なエンティティ フレームワーク モデル

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 には、カスタム ドキュメント文字列 "This is documentation for the ID property." が含まれています。Entity1.cs はそうではありません。ただし、多数のエンティティがあり、このファイルへのデバッグがやや遅い場合、Model.Designer.cs は非常に大きくなる可能性があります。いくつかの小さなファイル (エンティティごとに 1 つ) を持つことをお勧めしますが、生成されたコードで 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 に答える