2012-01-10 11 views
9

申し訳ありませんが、このタイトルはより具体的ではありません - これを簡単に説明する方法はわかりませんでした。 多対多の関係を持つTripsとLocationはありますが、Locationsはそれらを使用するTripsについて知る必要はありません。私はこれを表現するために、これらのエンティティを作成しました:Entity Framework - 関連エンティティの熱心な読み込み

public class Trip 
{ 
    public int TripId { get; set; } 
    public virtual IList<TripLocation> TripLocations { get; set; } 
} 

public class TripLocation 
{ 
    public int TripId { get; set; } 
    public int LocationId { get; set; } 

    public virtual Location Location { get; set; } 
} 

public class Location 
{ 
    public int LocationId { get; set; } 
    // Note: Intentionally no collection of Trips 
} 

私はそれがTripLocationsだが、私は熱心な負荷に自分の場所をTripLocationsを得ることができない熱心な負荷への旅行を得ることができます。私は豊富な組み合わせの組み合わせを試してみました。

IQueryable<Trip> query = from trip in context 
           .Include(r =>r.TripLocations) 
           .Include(r => r.TripLocations.Select(tl => tl.Location)) 
         select ride; 

何か提案がありがとうございました!

+0

「ride」とは何ですか? – tyron

+0

"trip"はごめんなさい – gruve

+0

なぜあなたのモデルに 'TripLocation'エンティティがありますか?このエンティティには、表示していない他のプロパティがありますか?それ以外の場合は、モデルからこのエンティティを削除し、 'Trip'と' Location'の間に直接多対多の関係を作成することができます。あなたの現在のモデルでは、実際には多対多の関係ではなく、2対1対多があります。 – Slauma

答えて

14

ここでシナリオを再作成して、すべての結果を1つのクエリで取得できました。

var a = from trip in context.Trips.Include("TripLocations.Location") 
     select trip; 

これだけです。それは私のデータベースに対してクエリされたものです。

SELECT 
[Project1].[TripId] AS [TripId], 
[Project1].[Name] AS [Name], 
[Project1].[C1] AS [C1], 
[Project1].[TripId1] AS [TripId1], 
[Project1].[LocationId] AS [LocationId], 
[Project1].[LocationId1] AS [LocationId1], 
[Project1].[Name1] AS [Name1] 
FROM (SELECT 
    [Extent1].[TripId] AS [TripId], 
    [Extent1].[Name] AS [Name], 
    [Join1].[TripId] AS [TripId1], 
    [Join1].[LocationId1] AS [LocationId], 
    [Join1].[LocationId2] AS [LocationId1], 
    [Join1].[Name] AS [Name1], 
    CASE WHEN ([Join1].[TripId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM [dbo].[Trips] AS [Extent1] 
    LEFT OUTER JOIN (SELECT [Extent2].[TripId] AS [TripId], [Extent2].[LocationId] AS [LocationId1], [Extent3].[LocationId] AS [LocationId2], [Extent3].[Name] AS [Name] 
     FROM [dbo].[TripLocations] AS [Extent2] 
     INNER JOIN [dbo].[Locations] AS [Extent3] ON [Extent2].[LocationId] = [Extent3].[LocationId]) AS [Join1] ON [Extent1].[TripId] = [Join1].[TripId] 
) AS [Project1] 
ORDER BY [Project1].[TripId] ASC, [Project1].[C1] ASC 

はUPDATE:MSDN blog

IQueryable<Trip> query = from ride in context.Set<Trip>() 
          .Include(t=>t.TripLocations.Select(l=>l.Location))          
         select ride; 

詳細情報:

あなたはラムダバージョンで維持したい場合は、これが作業を行います。

+0

ありがとうございました!あなたの答えは正しい軌道に乗っていることを確認し、別の観点から実際のコードを見てもらうようにしました(上記の例は実際のコードの関連部分があると思います)。 – gruve

+1

ラムダ相当品をありがとう。 – angularsen

0

ラムダ式に関して、あなたは@tyronのようにcontext.Setを使うことができます。そうでなければcontext.Tripsを使うことができます。たとえば、次の

、あなたは以下のようなあなたのDbContextクラスでタイプDbSetのプロパティを定義する必要があり、このコードを動作させるためには
IQueryable<Trip> query = from ride in context.Trips 
          .Include(t=>t.TripLocations.Select(l=>l.Location))          
         select ride; 

:DbSetを返すプロパティの定義

public DbSet<Trip> Trips { get; set; } 

がいいですが、同時にコンテキストにアクセスするのと同等です。それは組み合わせることもできる単なるコードスタイルです。

0

リレーションシップ・プロパティ(例:ロケーション)のVIRTUALキーワードを削除すると、遅延読み込みが無効になり、熱心な負荷になります。

関連する問題