EF6.0生成されたコードにコメントがない解決方法
目次
最初の試み0
これまでvs 2010やvs 2008を使っていた、ずっと使っていたEF 4.0以下のバージョン・・・以前は、Model FirstのEFデザインにも慣れていましたが、デザインインタフェースでアイデアをよりよく助けることができるような気がします.また、設計インタフェースでは、最終的に生成されたエンティティクラスに存在するテキストの説明も簡単に追加できます.
問題を発見する
インストールvs 2013の後、早速EF 6を試してみました.0……ここでは何万字も省略しています.以前に設計され完成したプロジェクトを開き、edmxファイルが含まれています.ef 6を見たいです.0生成コードとef 4.0の違いは何ですか.結果:ef 6.0(T 4テンプレート)で生成されたcsファイルに注釈(edmxのドキュメント)が含まれていないとは情けない.
まずef 4を振り返る.0生成されたコンテンツ
ef4.0関係メタデータ(みんなが見ているかどうか分からないが、どうせ私はよく見ていない)
#region EDM
[assembly: EdmRelationshipAttribute("Models", "HospitalProject", "Hospital", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(HNWMS.EFData.Hospital), "Project", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(HNWMS.EFData.Project))]
///... ...
[assembly: EdmRelationshipAttribute("Models", "UserMyDisk", "User", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(HNWMS.EFData.User), "MyDisk", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(HNWMS.EFData.MyDisk))]
#endregion
ef4.0 Container宣言
ef4.0のContainerがObjectContextコンストラクション関数(デフォルトで生成された)から継承するものは3つあります.
///
/// 。
///
public partial class Container : ObjectContext
ef4.0エンティティの集合
有公共的带有get访问器的属性,也有对应的私有字段。完全面向对象的写法;唯一不好的就是,没有自动生成实体集合的注释内容(summary)。
///
/// 。
///
public ObjectSet Users
{
get
{
if ((_Users == null))
{
_Users = base.CreateObjectSet("Users");
}
return _Users;
}
}
private ObjectSet _Users;
ef4.0 AddToメソッド
虽然表明了“已弃用”,但是,在其他地方调用的时候还是很方便,起码很直接。
///
/// Users EntitySet , 。 ObjectSet<T> .Add 。
///
public void AddToUsers(User user)
{
base.AddObject("Users", user);
}
ef4.0エンティティ宣言
加入了很多Attribute的声明,说实在的,我从来没有注意过这些东西,也不知道做什么用的。
///
/// ( )
///
[EdmEntityTypeAttribute(NamespaceName="Models", Name="User")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
[KnownTypeAttribute(typeof(ProjectManager))]
[KnownTypeAttribute(typeof(HospitalServicer))]
[KnownTypeAttribute(typeof(NursingWorker))]
public partial class User : EntityObject
ef4.0エンティティ構築関数
庞大到不敢看,参数是所有属性的排列,然后加上了个global::用以排除类型冲突;在开发的过程中,我似乎没有使用过实体构造函数来构造实体的实例。
public static User CreateUser(global::System.String code, global::System.String loginPassword, global::System.String realName, global::System.String mobilePhoneNO, global::System.String xType, global::System.String iDCordNO)
ef4.0ベース属性
実体集合と同様に,オブジェクト向けの書き方に完全に合致し,属性があり,対応するフィールドが存在する.さらにsetアクセサには、「自己追跡エンティティ」をトリガーする4つのイベント(自己追跡エンティティとは具体的には、ここでは説明しない)も表示されます.
///
///
///
///
/// :
U +4
4 9999
UA +3
///
[EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String Code
{
get
{
return _Code;
}
set
{
if (_Code != value)
{
OnCodeChanging(value);
ReportPropertyChanging("Code");
_Code = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("Code");
OnCodeChanged();
}
}
}
private global::System.String _Code;
虽然,我在上边的描述中说了提到了很多关于ef4.0中的“不好”,但是这并不表示我不认同ef4.0。下面说几点我理解的ef的好处:
- 我还是很喜欢ef的,因为其简单、易用,配合上mvc、WCF Data Service很容易就完成一个解决方案;
- 我更加喜欢vs提供的edmx设计器,在这里我可以不借助其他“构思辅助”软件,就可以完成“数据设计”以及“数据关系”的梳理工作。
- 通过edmx我可以很容易的为“实体”“属性”“导航属性”添加“文档”(在最终的代码中为summary,这也是我写这篇文章的目的。)
因为解决方案中存在有一个edmx文件,在其他人接手改解决方案时,很容易就可以看到数据设计,很容易就可以理解数据关系。
所以,在大家都在“喊叫”EF code first的时候,我仍然使用着model or db first。所谓“仁者见仁智者见智,萝卜白菜各有所爱”,大牛们别喷我。谢谢^_&.
EF 6を見てみましょう。0生成されたコンテンツ
ef6.0コンストラクタ
不同于EF4.0,在生成的Container上方,并没有出现很多的“元数据”内容。打开这个类的时候,给我的第一感觉就是,啊!好简单啊。
Container继承自DBContext,至于与ObjectContext有什么不同,请大家找度娘或者MSDN。
public partial class Container : DbContext
ef6.0エンティティセット宣言
ef 4.0はまず異なり、エンティティセットはObjectSetタイプではなくDBSetタイプです.次に、getとsetアクセサ(対応するフィールドの宣言が少なくなり、暗黙的なプロパティアクセサの宣言方法に合致する)を簡略化するのはよくありません.注釈そこに行った、ef 4.0少なくとも「メタデータドキュメントがない」というものがあります.に表示されます.
public virtual DbSet Users { get; set; }
ef6.0エンティティ宣言
ef 4.0は異なり、エンティティの構造関数はそれほど肥大化せず、パラメータがなく、内部でもナビゲーション属性に初期値を与えただけである.また、属性のgetやsetも簡略化されていて、一見、このようなクラスは誰が書いたDemoのようですね.しかし、エンティティセットの宣言と同じように、注釈はそこに行きました.ef 4.0ではedmxの「ドキュメントおよび長い説明」をsummaryに生成します.
public partial class User
{
public User()
{
this.SignIns = new HashSet();
this.MyMenus = new HashSet();
this.MyDisks = new HashSet();
}
public string Code { get; set; }
public string LoginPassword { get; set; }
public string RealName { get; set; }
public string MobilePhoneNO { get; set; }
public string xType { get; set; }
public string IDCordNO { get; set; }
public virtual ICollection SignIns { get; set; }
public virtual ICollection MyMenus { get; set; }
public virtual ICollection MyDisks { get; set; }
}
上は非常に簡単で浅いef 4を述べた.0とef 6.0の違いは、私個人の好き嫌いを述べています.
問題解決の必要性
ここを見ると、多くの牛が「弟さん、out manさん、みんな今2015にいますが、あなたはまだ2013ですか?」と言うかもしれません.「ひとつの注釈ではないか.その必要はあるのか」弟は私は说明して、ほほほ、何年があって、第一線で働いていないで、codeの仕事をしたことがなくて、だからvsとその他のエディタなどに対して、すべてあまり熟知していません......注釈はしかしとても重要で、特にvsの要求に合致する///summary注釈、vsは知能のヒントがあるため、私はみんながすべて见たことがあっても使ったことがあると思って、当.というときに、そのタイプの下の属性とか、方法とかがたくさん出てくるんですよね・・・.英語でお願いします.どうやって見分けますか?E文がいいとしても、あなたは一人でアプリケーションシステムを開発していますか?ほほほ、ちょっと強弁ですね.要するに、私は大声で叫びます“私は注釈を要します!私が書いたコードの注釈に関わらず、やはり生成したコードの注釈、私はすべて要します!また見なければならないのは注釈を理解します.”私より料理を持っている小鳥たちにこっそり教えて、実はvsの中のコードの(規範に合っている)注釈は、開発が完了した後、注釈を通じてchmタイプやhelp view 2を生成することができます.xタイプのヘルプファイルです(ここではあまり言いません).
問題を解決する
最初のステップでedmxに「コード生成項目」すなわち「EF 6.x DBContextジェネレータ」を追加する
手順:
第2ステップT 4テンプレートの内容を修正する
Model.Context.ttファイル
検索内容:
public string DbSet(EntitySet entitySet,System.Collections.Generic.IEnumerable.Data.Entity.Core.Metadata.Edm.GlobalItem> itemCollection)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} virtual DbSet {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet), summary);
}
この方法は何をしていますか.実は、次のコードのようなテキストを返します.
public virtual DbSet Users { get; set; }
変更内容:
public string DbSet(EntitySet entitySet,System.Collections.Generic.IEnumerable.Data.Entity.Core.Metadata.Edm.GlobalItem> itemCollection)
{
string summary = entitySet.ElementType.Documentation == null ? "(error message:not have summary in edmx.)" : entitySet.ElementType.Documentation.Summary;
return string.Format(
CultureInfo.InvariantCulture,
"/// \r
\t/// {3} \r
\t/// \r
\t{0} virtual DbSet {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet), summary);
}
ふふ、私が書いたFormatの中で、美しくないべきだと思うかもしれません....私の説明では、どうせこのT 4は最終的にプログラムセットにコンパイルされないので、どうでもいいということです.これにより、最終的に生成されたコンテンツは次のようになります.
///
/// ( )
///
public virtual DbSet Users { get; set; }
Model.ttファイル
找到内容:
foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
#>
このコードは、エンティティのタイプ名に基づいて独立したcsファイルを生成し、Namespace宣言を生成します.タイプにコメントを追加すると、Namespaceの下にあるのではないでしょうか.
string summary=string.Empty;
foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
summary = entity.Documentation == null ? entity.Name : entity.Documentation.Summary;
#>
///
///
///
还没有完成,继续,找到
public string Property(EdmProperty edmProperty)
{
return 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 navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{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)));
}
次のように変更します.
public string Property(EdmProperty edmProperty)
{
return string.Format(CultureInfo.InvariantCulture,
"/// \r
\t/// {5}\r
\t/// \r
\t{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)),
edmProperty.Documentation == null ? "" : edmProperty.Documentation.Summary
);
}
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"/// \r
\t/// {5}\r
\t/// \r
\t{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)),
navProp.Documentation == null ? "" : navProp.Documentation.Summary
);
}
次に「保存」すると、生成されたcsファイルは次のようになります.
///
/// ( )
///
public partial class User
{
......
///
///
///
public string Code { get; set; }
......
}
OK!これでedmx生成コンテンツにコメントがないという問題が解決した.再び「注釈が役に立つ!
まとめ
要するに、個人的には、新しいもの(他の人が一つのシリーズにまとめることができる)を使うときは、必ず設計者の立場から考えて、すべてのものが役に立つと思います.