2009-04-27 6 views
44

をロードしない()メソッドを含め、インクルード()メソッドは、もはや例えば、作業ではありません参加し、インクルード()がLINQのツーエンティティ私が参加し使用している場合は

リー

+0

どうしてそうだと思いますか?あなたはそれを実行した後に値を変更しませんか? – pocheptsov

+0

私は、「プロパティ」があなたがインクルードに渡す実際の文字列ではないと推測しています。これは、あなたが質問の最も重要な部分を省略したことを意味します。また、なぜ私はあなたがまったく結合を使用しているのか疑問に思います。ナビゲーションプロパティは一般的にEntity Frameworkの関係をトラバースする正しい方法です。 –

+0

pocheptsov - Proeprties.IsLoadedがfalseなのでPropertiesが読み込まれていないことが分かりました こんにちはCraig - "Properties"は正しい文字列です。ジョインは異なるナビゲーションプロパティにあります。私はItemオブジェクト(Collection.ID)のプロパティの値を持っているので、結合はそこにありますが、関連するエンティティが必要です。 Lee –

答えて

54

更新:実際に私は最近これをカバーする別のヒントを追加しました。アイデアは、インクルードの使用を遅らせることがある()クエリの終わりまで、より多くの情報のためにこれを参照してください。Tip 22 - How to make include really include


が知られている制限をエンティティフレームワークに含める使用している場合()。 特定の操作は、インクルードではサポートされていません。エンティティとプロパティの関係がある場合

var results = 
    from e in dc.Entities //Notice no include 
    join i in dc.Items on e.ID equals i.Member.ID 
    where (i.Collection.ID == collectionID) 
    select new {Entity = e, Properties = e.Properties}; 

これは、プロパティを取り戻すだろう、と:

はあなたがこのような何かを試してみてくださいこの問題を回避するために、これらの制限のいずれかに実行した可能性がありますように見えます

anonType.Entity.Properties 
anonType.Properties 

これは関係フィックスアップと呼ばれるEntity Frameworkの中の機能の副作用です:あなたは、各結果の匿名型が同じ値を持っていることがわかります多くの(しかし、多くの多くはない)に1。

詳細はTip 1EF Tips seriesをご覧ください。

+0

あなたの助けを借りて誠にありがとうございます – ChrisHDog

+1

これはまだですか?あなたが "新しい項目を選択する{...};" .Include()ステートメントは機能しません。 – grimus

+0

@grimus、クエリで生成された要素型がエンティティ型でない場合、 'Include'でクエリ全体をラップすることは現在動作していないようです。しかし、 'select'節の中でナビゲーションプロパティ値を取得するという元の提案は、これを回避するために動作するように思われます。 – Sam

0

は、多かれ少なかれ、同じことは、同じ結果を得るか へのより詳細な方法を試してみて、より多くで動作しますデータ集:

var mydata = from e in dc.Entities 
      join i in dc.Items 
       on e.ID equals i.Member.ID 
      where (i.Collection.ID == collectionID) 
      select e; 

foreach (Entity ent in mydata) { 
    if(!ent.Properties.IsLoaded) { ent.Properties.Load(); } 
} 

同じ(予期しない)結果が得られますか?

EDIT:最初の文を間違って変更しました。ポインタコメントありがとう!

+0

これは決して同じことではありません。あなたのコードはn + 1個のデータベースクエリになります。ここで、nは取り出された行の数です。 1つのデータベースクエリに結果を含めます。 –

+0

私は同じことをやっていないことを知っています - それは私が同じ結果で終わると言っているのはちょっとした方法でした。これを行う主な理由は、このようにロードされたプロパティがあるかどうかを確認することでした。そうでない場合、問題は.Include()構文ではなく、データ(関連付けられたプロパティレコードが欠落している可能性がある場所など)にあります。 –

+0

こんにちはトーマス Properties.Load()を使用してプロパティを読み込むと、正しくロードされます。 結合を含まないクエリに「Include( "Properties")」を使用すると、(e.ID = id) eを選択します。 正常に動作します。 Lee –

4

"Item.Member"(つまり、ナビゲーションのもう一方の端)に関連する "エンティティ"のナビゲーションプロパティの名前は何ですか。これを結合の代わりに使用する必要があります。例えば、「実体」は1のカーディナリティとメンバーというプロパティを追加し、会員は多くのカーディナリティとアイテムというプロパティを持っていた、あなたがこれを行うことができれば:

from e in dc.Entities.Include("Properties") 
where e.Member.Items.Any(i => i.Collection.ID == collectionID) 
select e 

私はのプロパティを推測していますあなたのモデルはここにありますが、これはあなたに一般的な考えを与えるはずです。 ほとんどの場合、LINQ to Entitiesでjoinを使用すると、間違ったになります。これは、ナビゲーションプロパティが正しく設定されていないか、使用していないことを示しているためです。

20

はこれを試してみてください:

var query = (ObjectQuery<Entities>)(from e in dc.Entities 
      join i in dc.Items on e.ID equals i.Member.ID 
      where (i.Collection.ID == collectionID) 
      select e) 

return query.Include("Properties") 
1

だから、私はここにパーティーに遅れています実現、しかし、私は私が私の調査結果を追加しようと思いました。これは本当にAlex Jamesの記事に対するコメントですが、私は評判がないので、ここに行かなければなりません。

私の答えは:それはあなたが意図するように全く動作していないようです。 Alex Jamesは2つの面白い解決策を挙げていますが、SQLを試してみると恐ろしいことです。

私が働いていた例がある:

 var theRelease = from release in context.Releases 
         where release.Name == "Hello World" 
         select release; 

     var allProductionVersions = from prodVer in context.ProductionVersions 
            where prodVer.Status == 1 
            select prodVer; 

     var combined = (from release in theRelease 
         join p in allProductionVersions on release.Id equals p.ReleaseID 
         select release).Include(release => release.ProductionVersions);    

     var allProductionsForChosenRelease = combined.ToList(); 

これは、2つの例の単純に従います。

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name] 
    FROM [dbo].[Releases] AS [Extent1] 
    INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID] 
    WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status]) 

しかし、OMGと::

SELECT 
[Project1].[Id1] AS [Id], 
[Project1].[Id] AS [Id1], 
[Project1].[Name] AS [Name], 
[Project1].[C1] AS [C1], 
[Project1].[Id2] AS [Id2], 
[Project1].[Status] AS [Status], 
[Project1].[ReleaseID] AS [ReleaseID] 
FROM (SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Id] AS [Id1], 
    [Extent3].[Id] AS [Id2], 
    [Extent3].[Status] AS [Status], 
    [Extent3].[ReleaseID] AS [ReleaseID], 
    CASE WHEN ([Extent3].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM [dbo].[Releases] AS [Extent1] 
    INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID] 
    LEFT OUTER JOIN [dbo].[ProductionVersions] AS [Extent3] ON [Extent1].[Id] = [Extent3].[ReleaseID] 
    WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status]) 
) AS [Project1] 
ORDER BY [Project1].[Id1] ASC, [Project1].[Id] ASC, [Project1].[C1] ASC 

総ごみ、それは完全に立派なSQLを生成含んなし。ここで重要なのは、status = 1で制限されていないテーブルの外部結合バージョンを返すという点です。間違ったデータで

この結果が返される:2の状況は、私たちの制限にもかかわらず、そこに返されていることを

Id Id1 Name  C1 Id2 Status ReleaseID 
2 1 Hello World 1 1 2  1 
2 1 Hello World 1 2 1  1 

注意。単に機能しません。 もし私がどこかで間違ってしまったら、これがLinqの嘲笑をしているので、私は喜んで見つけられるでしょう。私はこのアイデアが大好きですが、実行は現時点では使えないようです。


は好奇心から、私が試したLinqToSQL DBMLむしろ上記の混乱を生じLinqToEntitiesのEDMXより:

SELECT [t0].[Id], [t0].[Name], [t2].[Id] AS [Id2], [t2].[Status], [t2].[ReleaseID], (
    SELECT COUNT(*) 
    FROM [dbo].[ProductionVersions] AS [t3] 
    WHERE [t3].[ReleaseID] = [t0].[Id] 
    ) AS [value] 
FROM [dbo].[Releases] AS [t0] 
INNER JOIN [dbo].[ProductionVersions] AS [t1] ON [t0].[Id] = [t1].[ReleaseID] 
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [t2] ON [t2].[ReleaseID] = [t0].[Id] 
WHERE ([t0].[Name] = @p0) AND ([t1].[Status] = @p1) 
ORDER BY [t0].[Id], [t1].[Id], [t2].[Id] 

もう少しコンパクト - 奇妙数句が、全体的に同じ総FAIL。

実際のビジネスアプリケーションでこのようなことを実際に使用したことがありますか?私は本当に不思議に思っています... 私は本当にLinqが欲しいと思っているので、私は何か明白な逃したことを教えてください!

関連する問題