Сначала добавьте документацию к сгенерированному коду в модели инфраструктуры сущностей

Я использую модель Entity Framework впервые с VS 2010. Когда я создаю свой проект, EF создает файл Model.Designer.cs, содержащий все сущности. Этот файл конструктора также содержит документацию, добавленную к объектам в файле EDMX.

Когда я создал первый проект новой модели EF в VS 2012, файл 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>

Сгенерированный класс (Entity1.cs) с помощью Model.tt выглядит следующим образом:

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 в сгенерированном коде.


person Chris    schedule 18.12.2012    source источник
comment
Вы должны изменить свой файл T4, чтобы включить документацию в сгенерированный код. Может быть, вы можете выложить файл T4?   -  person knaki02    schedule 18.12.2012
comment
Я мог бы выложить файл T4, но это было бы довольно длинно. Кроме того, я не изменил это. Это стандартный файл, предоставленный VS. Я также предпочел бы не менять это, так как предполагаю, что мне придется делать это для каждого проекта. Обновления VS, изменяющие файл, также будут потеряны.   -  person Chris    schedule 19.12.2012
comment
Вы можете изменить файл шаблона, который будет использоваться в ваших следующих проектах...   -  person knaki02    schedule 19.12.2012


Ответы (1)


Я думаю, вам придется изменить файл 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)#>
person Dennis Nguyen    schedule 04.01.2013