2013-04-23 7 views
7

特定のユーザーの個別のキャンペーンを探す必要があります。ユーザーにはCodeRights、CodeRightsにはコードとコードが含まれています。ここでCodeRightクラスですEntity Frameworkが実行しているクエリが多すぎます

public class SmartCodeRight 
{ 
     [Key, Column(Order = 1)] 
     public long UserId { get; set; } 
     public virtual User User { get; set; } 

     [Key, Column(Order = 2)] 
     public long CodeId { get; set; } 
     public virtual SmartCode Code { get; set; } 

     public CodeRight CodeRight { get; set; } 
} 

私はこのために、次のSQL記述します。

var v = user.CodeRights.Select(r => r.Code.Campaign).Distinct().ToList(); 

今すぐプロファイリングに私がいることを見ています:私はこのコードを書いていEFを使用して

SELECT * 
FROM campaigns 
WHERE campaignid IN (SELECT DISTINCT campaignid 
        FROM smartcodes t1 
        INNER JOIN smartcoderights t2 ON t1.codeId = t2.codeId 
        WHERE t2.userid = @userId) 

をEFは、存在するすべてのCodeRightに対して2つのSQLクエリを実行しています。

私はまた全体の実行時間を計算しました。EFはADO.Netを使用している間〜400ミリ秒かかります。それは~8です。

私の質問は、EFが本当に遅いか、何か間違っていると思いますか?二つのブロックに続いて

編集

はあなたがFetch Plans for Entity Frameworkを見て時間を費やす必要があり、すべてのCodeRight

exec sp_executesql N'SELECT 
[Extent1].[CodeId] AS [CodeId], 
[Extent1].[CodeTitle] AS [CodeTitle], 
[Extent1].[CodeContent] AS [CodeContent], 
[Extent1].[CreatedOn] AS [CreatedOn], 
[Extent1].[IsActive] AS [IsActive], 
[Extent1].[Deleted] AS [Deleted], 
[Extent1].[OwnerId] AS [OwnerId], 
[Extent1].[Tags] AS [Tags], 
[Extent1].[CampaignId] AS [CampaignId] 
FROM [dbo].[SmartCodes] AS [Extent1] 
WHERE [Extent1].[CodeId] = @EntityKeyValue1',N'@EntityKeyValue1 bigint',@EntityKeyValue1=24 
go 

exec sp_executesql N'SELECT 
[Extent1].[CampaignId] AS [CampaignId], 
[Extent1].[Name] AS [Name], 
[Extent1].[Description] AS [Description], 
[Extent1].[AdminId] AS [AdminId] 
FROM [dbo].[Campaigns] AS [Extent1] 
WHERE [Extent1].[CampaignId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=12 
go 
+0

は、クエリを実行するコードを表示することができます:

それはあなたのuserオブジェクトを取得するとき、あなたの最初のクエリの一部である必要がありますか?この質問(http://stackoverflow.com/questions/8473705/linq-to-entities-distinct-on-one-column)は、EFが「DISTINCT」を使用して適切なクエリを生成する必要があることを示します。 –

+4

ORMのトレードオフは彼らは "チャット"です。ほとんどの場合、パフォーマンスは「十分に良い」ものです。しかし、彼らは冗談です。しかし、カスタムORMコードを書く時間が少なくて済みます。毒を選ぶ。 EFがどのようにクエリを発行し、追加する価値のあるインデックスがあるかを確認することができます。 – granadaCoder

+0

@ w.brian編集内容をご覧ください。 –

答えて

10

のために実行されています。 EFが参加を実行するには、Includeキーワードを使用する必要があります。

var user = context.Users 
    .Include("CodeRights.Code") 
    .Include("CodeRights.Campaign") 
    .FirstOrD‌​efault(u => u.Id == id); 
+0

CodeRightsはCodeRight型のコレクションなので、そこに「Include」を入れることはできません。 –

+1

'Include'は、' var user = context.Users.Include( "CodeRights.Code")のようなユーザを返すクエリの一部である必要がありますInclude( "CodeRights.Campaign")。FirstOrDefault(u = > u.Id == id); ' –

+0

@ApurvGuptaが更新されました。 – mattytommo

関連する問題