2012-01-26 6 views
0

私は非常に単純なデータモデルを持っています(下記)。ナビゲーションプロパティをデータベースからロードする方法を調べるのに問題があります。私はそれらを取得するのに問題はありませんが、ナビゲーションプロパティはEFによって設定されていませんが表示されます。私はいくつかの関連する質問を見てきましたが、少し異なっていたり、むしろ関与しています。私はEF 4.2(POCO)によってナビゲーション特性がどのように扱われるかについての情報を探しています。私が行った読書では、ナビゲーションプロパティを使って外部キーを持つオブジェクトにアクセスできるという印象を受けました。その代わりに、コンストラクタでコレクションをインスタンス化するかどうかによって、プロパティがnullまたは空に戻ってきます。EF 4.2 POCOでデータベースから検索すると、ナビゲーションプロパティがnullになるのはなぜですか?

public class AnimalDb : DbContext 
{ 
    public static AnimalDb Create(string fileName) 
    { 
     Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0"); 
     return new AnimalDb(fileName); 
    } 

    private AnimalDb(string fileName) : base(fileName) { } 

    public DbSet<Animal> Animals { get; set; } 
} 

public class Animal 
{ 
    public Animal() 
    { 
     Id = Guid.NewGuid(); 
     Traits = new ObservableCollection<Trait>(); 
    } 

    public Guid Id { get; set; } 
    public string Species { get; set; } 
    public string Name { get; set; } 
    public ObservableCollection<Trait> Traits { get; set; } 
} 

public class Trait 
{ 
    public Trait() 
    { 
     Id = Guid.NewGuid(); 
    } 

    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

そして、ここでそれを使用して、いくつかの(簡単な)コードです:

foreach (var animal in db.Animals) 
{ 
    foreach (var trait in animal.Traits) 
    { 
     //animal.Traits count is 0, so this does not run. 
     //However there are traits in the database, as my populate 
     //function is working fine. 
     Console.WriteLine("{0} is {1}", animal.Name, trait.Name); 
    } 
} 

----編集回答の概要----答えで提供記事や情報を使用して

以下では、db.Animals.Include()を使って熱心に読み込んだり、遅延読み込みを可能にしたりすることができました。遅延ロードを有効にして、それを使用できるというトリックがあります。私は次のように私のトレイトコレクションを変更

db.Configuration.LazyLoadingEnabled = true; 

次へ:私は追加遅延ロードを有効にするにはまず、仮想作る

public virtual ObservableCollection<Trait> Traits { get; set; } 

を遅延トレイトをロードする自動的に生成されたプロキシすることができます。それでおしまい! IMHO私はMSDNのドキュメントがこの負荷を叫び、POCO EF 4.2コーディング規約で明確にすべきだと思います。もう一度助けてくれてありがとう。

+1

私はEF 4.2で多くのことをしていませんが、EF 4ではレイジーロードとプロキシを有効にする必要があります。そうしないと、ObjectContextに明示的にNavプロパティをロードする必要があります。 ) 'または' ObjectQuery.Include() 'です。 'DbContext'と同じですか? – CodingGorilla

+0

これらのようなObjectContextメソッドにアクセスしようとしましたが、DbContext経由で利用できないようです。 – Nate

+1

'DbContext'を使用しているときに' ObjectContext'と同じメソッドにアクセスすることはできませんが、それは小さなサブセットです。詳細はこちら:http://msdn.microsoft。com/en-us/library/gg696165(v = v103).aspx – CodingGorilla

答えて

1

あなたが明示的にInclude法との関係をロードするためにEFを指示する必要があります熱心なローディングの詳細についてはthis articleをご覧ください。

+0

これはちょうど動作します。まだ記事を読んでいるが、これが私の特定の問題で使用するルートになると思われる。ありがとう。 – Nate

2

ワイヤーアップの方法にデータがないように見える理由がいくつかあります。関連データをロードするには以下を行う必要があります。

  • 明示的には
  • が遅延ロードの要件を満たすデータをロード、または
  • Include()

私の推測では、あなたがオフになっていることである使用して熱心なロードを使用仮想プロキシ要件の詳細は、ここにあります:

foreach (var animal in db.Animals.Include(a => a.Traits)) 
{ 
    foreach (var trait in animal.Traits) 
    { 
     //... 
    } 
} 

あなたが読むことができます:あなたが遅延ロードを使用しない場合は

http://msdn.microsoft.com/en-us/library/dd456855.aspx

+0

私はおそらくあなたが引用した最後の2つの箇条書きにたいへん興味があります。私は、Include()が短期的には私の最善のルートだと見ていますが、遅延ロードがどのように達成されているかを理解しようとしています。この単純な例では、POCOのデフォルトをオーバーライドしていないので、仮想プロキシがどのようにオフになったのかわかりません。アドバイスをいただきありがとうございます。 – Nate

+1

遅延ロードを使用するには、キーをオンにし、プロパティを仮想に設定することが重要でした。言い換えれば、私は遅延ロード要件を満たしていました。ありがとう。 – Nate

+0

@ネイトええ、遅延読み込みはオンにするのは大したことではありません。この変更により、T4テンプレートはすべてのプロパティに 'virtual'という単語を追加し、プロキシはオンになります。プロキシがオーバーヘッドを追加することに気をつけてください。また、怠惰な読み込みがどのようにしてクエリを起動させるのかを感じるまで、SQLプロファイラを実行します。 – EBarr

関連する問題