2013-04-23 15 views
7

Belirli bir kullanıcının farklı Kampanyalarını bulmam gerekiyor. Bir kullanıcının CodeRights özelliği vardır, CodeRights Kodları ve Kodları içerir Kampanya içerir. İşte CodeRight sınıftırVarlık Çerçevesi çok fazla sorgu çalıştırıyor

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; } 
} 

Bunun için aşağıdaki SQL yazarsınız:

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

Şimdi profilleme taki görüyorum: Bu kodu yazıyorum EF kullanma

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, her CodeRight hediyesi için 2 SQL sorgusu yürütmektedir.

Ayrıca, tüm yürütme zamanını hesapladım ve EF, ~ 400 ms alırken ADO.Net kullanırken yalnızca ~ 8.

Şimdi sorum şu: EF gerçekten bu kadar yavaş mı yoksa yanlış bir şey mi yapıyorum? İki bloktan ardından

Düzenlemeleri

Sen Fetch Plans for Entity Framework bakarak zaman harcamak gerektiği her 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 

ve

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

sorguyu çalıştırmadan kod gösterebilir:

Bu sizin user nesne olsun, başlangıçtaki sorgunun parçası olmak gerekecek? Bu soru (http://stackoverflow.com/questions/8473705/linq-to-entities-distinct-on-one-column), EF'in "DISTINCT" –

+4

kullanarak uygun bir sorgu oluşturması gerektiğini gösterir. onlar "konuşkan". Çoğu zaman performans "yeterince iyi". Ama onlar konuşkan. Ancak, özel ORM kodu yazarken daha az zaman harcıyorsunuz. Bir zehir seç. Yapabileceğinizi düşündüğünüz şey, EF'in sorguyu nasıl belirlediğini görmek ve eklenmeye değer bir endeks olup olmadığını görmek. – granadaCoder

+0

@ w.brian Lütfen düzenlemelere bakın. –

cevap

10

için yürütülmektedir. EF'in birleştirme işlemini yapabilmesi için Include anahtar kelimesini kullanmanız gerekir.

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

CodeRights, CodeRight türünün bir koleksiyonudur, bu nedenle orada "Dahil Et" özelliği olamaz. –

+1

'Include ', kullanıcının döndürdüğü bir sorgunun parçası olmalıdır, örneğin var user = context.Users.Include (" CodeRights.Code "). Include (" CodeRights.Campaign "). FirstOrDefault (u = > u.Id == id); –

+0

@ApurvGupta Güncellendi. – mattytommo