2011-11-30 2 views
8

私は、Entity Frameworkに最新のリリースには多くの「自動」機能があることに気付きました。いつものように、これは真に両刃の剣です。Entity Framework Code Firstで自動リレーションシップを無効にすることはできますか?

具体的には、FluentAPI(http://msdn.microsoft.com/en-us/library/hh295844(v=vs.103))を使用して、OnModelBuilderイベントを使用してオンザフライでモデルを作成しています。 .aspx)。私は多数のエンティティを持っており、すべてがMicrosoftの "標準"に準拠しているわけではありません。たとえば、私のID列の名前はPersonIdではなくPerson_idです。そのため、Entityはテーブルのプライマリキーを常に自動的に検出するとは限りません。少なくとも、そうではないようです。 エンティティが自動的に検出するプロパティとリレーションシップと、誤って無視するか間違っているのかが必ずしもわからないのですが、それは間違いです。ほとんどのエンティティもヘルパーメソッドとプロパティ(enumなどを処理するためのもの)を持つ部分クラスを持っているので、いつかエンティティがマッピングされるべきでないものの間で自動的にマッピングを作成することを恐れていますいくつか疑いのないプログラマー)。

私のOnModelBuilderメソッドで100%明示的にすることができるように、Entityの自動関係フックアップ機能を無効にする方法はありますか?または、少なくとも、追加のマッピングの詳細を追加する必要があるとき(特定のフィールドを宣言する必要があるときや特定のナビゲーションプロパティが自動検出されないときなど)には、どうすればわかりますか?

ありがとうございました!

+0

このようなことが心配なのであれば、新しい "コードファースト"のものではなく、EFの "デザインファースト"の側面を使うべきでしょう。 –

+0

私は偶然EDMXで始まりました。私は、コードを最初に思いつくように「アップグレード」しようとしていました。それは、コード内にあるので管理しやすくなるかもしれませんが、努力と時間をデバッグするだけの価値はないかもしれません。 – Brett

答えて

6

オートマジックは、最初のEFコード内の規則によって行われます。あなたはconventionsのいずれかを削除していくつかの魔法を消すか、remove them allとすることができます。その後、流暢なAPIで100%明示的にする必要があります。

+0

うわー!これはまさに私が必要としていたものです! – Brett

+0

EF6ですべての表記規則が削除されても助けにならない...最終的に私の答えとコードスニペットが表示されます。 – baHI

0

あなたのエンティティ設定のあなたの関係、キー、カラムを明示してください。実際には問題ではありません。

私は個人的には、コーディング中に、それが壊れるまで想定してから、構成を修正します。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    Database.SetInitializer<AccountWriteContext>(null); 

    modelBuilder.Configurations.Add(new AccountEntityTypeConfiguration()); 
    modelBuilder.Configurations.Add(new AccountOwnerEntityTypeConfiguration()); 
    modelBuilder.Configurations.Add(new CreditCardEntityTypeConfiguration()); 
    modelBuilder.Configurations.Add(new TenantEntityTypeConfiguration()); 
    //blah blah blah 
} 


class AccountOwnerEntityTypeConfiguration 
    : EntityTypeConfiguration<AccountOwner> 
{ 
    public AccountOwnerEntityTypeConfiguration() 
    { 
     this.HasKey(p => p.ID); 
     this.Property(p => p.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired(); 

     this.HasRequired(o => o.CreditCard).WithMany().HasForeignKey(c => c.CreditCardID).WillCascadeOnDelete(true); 

     this.ToTable("AccountOwner", "AccountWrite"); 
    } 
} 
+0

これは書かれているように決して機能しませんでした。たとえ正確な例であっても、私がAccountOwnerエンティティに入り、プロパティを追加すると、EntityTypeConfigurationに追加しなくても、自動的に次の移行でプロパティを追加します。 2011年は – Suamere

+0

でした。 – William

-2

データアノテーション属性を使用してこれを行うことをおすすめします。たとえば、[key]属性を使用して主キーを定義し、[table]属性を使用してテーブルの名前を指定することができます。 [required]属性を使用して、フィールドが必要であることをEFに伝えることができます。

私の意見では、属性の構文を使用する方が流暢な構文を使用してモデルを更新するよりも簡単であり、属性はオブジェクトコードに直接配置されるため、自己文書化もします。

詳細情報については、可能なすべての属性を一覧表示し、このブログ記事を参照してください。

http://blogs.msdn.com/b/efdesign/archive/2010/03/30/data-annotations-in-the-entity-framework-and-code-first.aspx

+0

質問は「無効にする方法」でした。そして私は、どの列を無効にするかを明示せずに仮定します。注釈や流暢な構文を好むかどうかは関係ありません。目標は、新しいプロパティを無視するように明示的に指示する必要なく、安定したマッピングを持つことです... – baHI

0

実はこのコードは、すべての規則を削除しても...

を初期設定をクリアします...しかし取り除くので、まだEntityTypeConfigurationにマッピングされていないカラムは、...

private void RemoveAllConventions(DbModelBuilder modelBuilder) 
     { 
      new List<string>() 
      { 
      "_configurationConventions", 
      "_conceptualModelConventions", 
      "_conceptualToStoreMappingConventions", 
      "_storeModelConventions" 
      } 
      .ForEach(field => 
      { 
       var values = 
        (IEnumerable<IConvention>)typeof(ConventionsConfiguration) 
         .GetField(field, BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic) 
         .GetValue(modelBuilder.Conventions); 

       modelBuilder.Conventions.Remove(values.ToArray()); 
      }); 

      var initialCS = typeof(ConventionsConfiguration) 
         .GetField("_initialConventionSet", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic) 
         .GetValue(modelBuilder.Conventions); 

      new List<string>() 
      { 
      "ConfigurationConventions", 
      "ConceptualModelConventions", 
      "ConceptualToStoreMappingConventions", 
      "StoreModelConventions" 
      } 
      .ForEach(field => 
      { 
       var values = 
        (IEnumerable<IConvention>) initialCS 
         .GetType() 
         .GetProperty(field, BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public) 
         .GetValue(initialCS); 

       modelBuilder.Conventions.Remove(values.ToArray()); 
      }); 


     } 
+1

投稿されたコードがその質問に答えるかどうかは本当にはっきりしていません。これはあなたの現在の状態ですか?それでもまだ動作しませんか?それとも、これで問題は解決しますか?他の質問につながりますか? – Tunaki

1

は[OK]をマッピングされていますEF6内で構成されていないすべてのプロパティをマッピングしない簡単な方法があります。x

基本的なことは、別々のマッピングクラスを使用し、クラス内のマニュアルマップを実行した後、単純にリフレクションを使用して構成されていないすべてのプロパティを無視するメソッドを呼び出します。

ここには実装がある私の要点へのリンクがあります。また、サンプルをコメントとして追加しました:https://gist.github.com/hidegh/36d92380c720804dee043fde8a863ecb

+0

これはすべてのプロパティ、つまりコレクション(1:n)または他の参照(n:1)に対しても有効です。 – baHI

関連する問題