流れるようなインターフェースは属性よりも柔軟性がありますか?


15

EF 4.1 Code Firstチュートリアルでは、次のコードが提供されています。

public class Department
{
    public int DepartmentId { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Collaborator> Collaborators { get; set; }
}

次に、流れるようなインターフェイスがより柔軟であることが説明されています。

データアノテーションは間違いなく簡単に使用できますが、はるかに柔軟性の高いプログラムによるアプローチを使用することをお勧めします。

流れるようなインターフェースの使用例を次に示します。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Department>().Property(dp => dp.Name).IsRequired();
    modelBuilder.Entity<Manager>().HasKey(ma => ma.ManagerCode);
    modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .IsConcurrencyToken(true)
        .IsVariableLength()
        .HasMaxLength(20);
}

流なインターフェースがおそらく優れている理由がわかりません。本当か?私の観点からは、データ注釈はより明確で、より明確なセマンティックな感覚を持っているように見えます。

私の質問は、特にこの場合、属性を使用するよりも流なインターフェイスが優れた選択肢になるのはなぜですか?

(注:流なインターフェイスの概念全体はまったく新しいので、これに関する予備知識がないことを期待してください。)

参照:http : //codefirst.codeplex.com/


この質問は、実際には流fluentなインターフェイスに関するものではありません。違いは、属性の使用と通常のコードの違いです。コードが流fluentでなければ、それはあなたの質問についてあまり変わらないでしょう。
-svick

@svick fluentインターフェースは基本的に通常のコードですが、別の方法で表現しています。単純なコードで属性に物事を指定することから遠ざかり、今では流なインターフェイスで、一部がバックトラックし、コードで物事を再度指定するようになっているように見えます。属性の代わりにコードを使用する理由を理解したいだけです。流なインターフェイスは、属性から離れてすべてを単純にコーディングし直すことを保証しますか?
Tjaart

回答:


13

データ注釈は静的です。たとえば、このメソッド宣言は実行時に変更できません。

  [MinLength(5)]
  [MaxLength(20,ErrorMessage="Le nom ne peut pas avoir plus de 20 caractères")]
  public new string Name { get; set; }

流れるようなインターフェイスは動的にすることができます:

   if (longNamesEnabled)
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(100);
   }
   else
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(20);
   }

言うまでもなく、コードはプロパティ間で再利用できます。


2
なぜ同じプロパティの長さ(または他のプロパティ)が実行時に変わると思いますか?
ユスボフ

1
@ElYusubov:コーディング時にフィールド長がわからないシナリオから始めます。
ワイアットバーネット

@WyattBarnett:ドメインパラメーターが何らかのサービスまたは外部の型指定されていないソースから動的にフェッチされる場合にのみ、フィールドの長さを変数として持つことは理にかなっています。ただし、ドメインプロパティを動的に処理するには、防御的なコーディングアプローチが必要です。
ユスボフ

1
@ElYusubovには、長さを除いてまったく同じである必要がある2つのプロパティがあるため、それらを動的に設定する関数に渡します。これが著者が彼らをより柔軟と呼んだ理由です。
ギャレットホール

1
@ElYusubov、フィールドの長さをプロジェクト設定の設定にして、app.configまたはweb.configにフィードすることができます。その後、データベースフィールドの長さが変更された場合、アプリを再コンパイルおよび再デプロイせずに.configファイルの長さを変更できます。
キラレッサ

8

その声明は広く適用されるべきではないと思います。Code Firstに非常に固有です。Code Firstでは、データ注釈には、Fluent APIで使用可能な機能のサブセットのみが含まれます。つまり、流れるようなAPIを使用してのみ実行できる特定のモデル構成があります。

たとえば、注釈を使用して指定できないものの一部を次に示します。

  • DateTimeプロパティの精度
  • 数値プロパティの精度とスケール
  • 固定長としての文字列またはバイナリプロパティ
  • 非UnicodeとしてのStringプロパティ
  • 関係の削除時の動作
  • 高度なマッピング戦略

個人的には、可能な限り検証関連のデータアノテーションを使用する傾向があります。MVCのような他のテクノロジーもこれらを利用できるからです。他のすべてについては、流れるようなAPIを好みます。


Fluent APIを使用しないとできないことの例を挙げていただけますか?また、なぜこのように選択したのかを知ることも興味深いでしょう。より多くの従来のメソッドとエンティティフレームワークに対してfleunt APIを理解しようとすることは、ほんの一例です。私は彼らが属性よりもそれを好む理由を知りたいです。私にとって、属性はより正確で読みやすいようです。
Tjaart

1
@Tjaartいくつかの例を追加しました。これを設計する際、2つの主な動機付けの原則がありました。まず、開発者が選択できるようにします。属性をPOCOの違反と見なす人もいれば、宣言的な性質を好む人もいます。第二に、既存の属性を活用し、一般的なシナリオのために新しい属性のみを導入します。上記の例が比較的一般的ではないことにおそらく同意するでしょう。
ブリセラム

OnDeleteの動作は、流れるようなAPIでのみ使用できるように見えることに気付きました。彼らがこのようにそれを選んだ理由を考えることができますか?これが本当にこの質問で私がやろうとしていることです。プロジェクト間でクラスを共有している場合、POCO違反が正当な理由になる場合があります。属性を使用する場合は、不要なエンティティフレームワークの依存関係を取り込むことになります。
Tjaart

@Tjaart、私は正確な理由を覚えていません。私はCode First機能の終わりに向かってチームに参加しましたが、設計のためにここにはいませんでした。しかし、チームから他の誰かを引き入れることができるかどうかを確認します。
ブリセラム

1

質問への回答はリンクに記載されています。

次に、このメソッド内でドメインに適用可能な制約をプログラムで定義します。

基本的に、属性よりもプログラムによるアプローチの方が多かれ少なかれ優先されます。プログラムによるアプローチでは、エンティティをより詳細に制御できます。ただし、モデルを装飾するために属性を追加するカスタムの方法もありますが、これも同様に見えます。

このアプローチを使用する場合、テーブルと列の間の関係を記述することもできます。結論として、ドメインをよりきめ細かく制御したい場合は、EF4.1に付属するこの新しいアプローチを使用できます。

ただし、検証の一般的なシナリオでは、属性の適用はほとんどの場合をカバーする堅牢なため、正常に機能するはずです。さらに、時間を節約できる可能性があります。


プログラムによる方法でどのように制御できるかを説明できますか?私はこの時点でそれを本当に得ていません。
-Tjaart

たとえば、これを ".IsConcurrencyToken(true)"とします-属性定義でこれを行うにはどうしますか?
ユスボフ

[ConcurrencyCheck] <-実際には単純に見える
Tjaart

それでは、「テーブルと列の関係」をどのように説明しますか?
ユスボフ

[ForeignKey( "PersonId")] <-のように、おそらく.HasForeignKey(t => t.ProjectId)ほど簡単ではありませんが、必要なのは、流KeyなインターフェイスのようにForeignKey()にラムダを取得させることだけです。一方が他方より優れている理由はまだ説明されていません。
-Tjaart

0

私は、データベースでリレーションシップがどのように作成されるかを明示的に説明しているため、コードファーストの実装には流れるようなAPIを推奨していると考えています。データ注釈を使用する場合、Entity Frameworkによって作成されたデータベースは期待したものとは異なる場合があります。最初の例は非常に単純なので、あなたと同じように、データ注釈メソッドを使用します。


データベースが期待したものではないという例と、流なインターフェイスがこれを防ぐ方法を教えてください。
Tjaart
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.