2010-12-15 5 views
1

エンティティフレームワークを初めて使用しました。私はMVCで、Ninjectを使ってマルチティアアプリケーションを作成しました。
データベースに3つのテーブルがあります。表A、表Bおよび表Cを参照してください。エンティティフレームワークエンティティが関連エンティティのプロパティを表示しない

Table A has a foreign key relating it to Table B 
Table B has a foreign key relating it to Table C 

Table A => Table B => Table C 

マイアプリケーションにはMVCコントローラから呼び出される「サービス」があります。
このサービスは、EF DataContextからのエンティティの作成、読み取り、更新、または削除を担当するすべてのエンティティ(つまりTableAService、TableBService)のリポジトリとして機能し、これらのエンティティでビジネスロジックを実行する可能性があります。

私のMVCコントローラ内には、適切なサービスへの参照があります。例えば:、

private EFDataContext _dataContext; 

public TableAService(EFDataContext dataContext) 
{ 
    _dataContext = dataContext; 
} 

public TableA GetById(int tableAId) 
{ 
    _dataContext.TableA.SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

私は例のサービスがしっかりデータソースに結合されることを理解、私の実際の実装は若干異なりますが、考え方は同じです:

private TableAService _tableAService; 

public TableAController(EFDataContext dataContext) 
{ 
    _tableAService = new TableAService(dataContext); 
} 

public ActionResult Index() 
{ 
    return View(); 
} 

TableAServiceは、次のようになります私はエンティティを返すことを望むdataContextを持つサービスを持っています。質問: - 私がTableAServiceのGetByIdメソッドに入っているとき、SingleOrDefaultは私にTableBナビゲーションプロパティを与え、TableCナビゲーションプロパティを含むすべてのTableBのプロパティにアクセスできます。

しかし、TableAをコントローラに戻すと、TableBのプロパティにアクセスできなくなります。

private ObjectSet<TableA> _objSet = _dataContext.CreateObjectSet<TableA>(); 

return _objSet.SingleOrDefault(ta => ta.TableAId == tableAId); 

これはからTableBの上TableCのナビゲーションプロパティにアクセスすることができることに任意の違いを確認していないようです。私も試したサービス内で

TableAエンティティ。

ご協力いただければ幸いです!あなたは、同様に使用することをTableCのレコードを取得したい場合は

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

乾杯、

ジェームズ

答えて

0

掘り出し物がありましたが、問題は私のアプリケーションがSystem.Data.Entityを参照していないことでした。

アプリケーションへの参照を追加すると、コントローラ内から関連オブジェクトのプロパティにアクセスすることができました。

回答ありがとうございました。彼らは可能性を排除するのに役立ちました。私はそれぞれ投票しました。

2

はにあなたのGetById方法を変更してみてください

public TableA GetById(int tableAId) 
{ 
    return _dataContext.TableA.Include("TableB.TableC").SingleOrDefault(ta => ta.TableAId == tableAId); 
} 

理由はEntity Frameworkが「レイジーローディング」を使用しているということです。あなたが本当に必要とするまでデータベースからロードされません。問題は、一度サービスを終了すると、テーブルBレコードを取得するためのデータコンテキストが存在しなくなることです。 Includeメソッドは、関連するテーブルのデータをすぐに読み込むようにEFに指示します。

3

ナビゲーションプロパティの内容は、アクティブなObjectContextのスコープ内にしかロードできません。

これは、実際の行がデータベースへのラウンドトリップによってフェッチされるため必要です。
最初にエンティティを取得するために使用されたObjectContextが削除され、接続が失われた後、ナビゲーションプロパティにアクセスしようとしています。

  • イーガーロード::関連企業が正面をアップロードされ、それはあなたが明示的にしながら、Entity Frameworkのは、すべての関連エンティティをロードするように指示しているあなたはEntity Framework 4この問題の2通のソリューションがありますを使用していると仮定すると、

    クエリの結果を取得しています。
    これは、クエリの投影に関連するエンティティを含めるか、ObjectQuery.Includeメソッドを呼び出すか、またはナビゲーションプロパティのLoadメソッドを呼び出すか、ObjectContext.LoadPropertyメソッドを呼び出すなど、さまざまな方法で実行できます。

  • 遅延ロード:関連エンティティは、オンデマンドでロードされます。つまり、ナビゲーションプロパティのゲッターに最初にアクセスされたときです。それでもObjectContextのスコープ内でこれを行う必要があることに注意してください。

    public TableA GetById(int tableAId) 
    { 
        return _dataContext.TableA 
         .Include("TableB.TableC") // use dot-notation to specify depth in the object graph 
         .SingleOrDefault(ta => ta.TableAId == tableAId); 
    } 
    

    関連リソース:

    Include方法を使用して、あなたの場合積極的なロードで

は、おそらく最も適切なソリューションです。

関連する問題