2012-07-04 11 views
5

veritabanından veri almak ve daha sonra tek tek her özellikte .sum kullanan tüm tek tek özellikleri toplamak için başka bir işlevi bu işlevi çağırmak için Linq kullanan bir işlevi vardır. Tüm mülkleri .Sum() 'ı her bir mülk üzerinde aramak yerine, bir kerede tüm mülkleri toplamanın etkili bir yolu olup olmadığını merak ediyordum. Sanırım şu an yaptığım gibi, çok yavaş (test edilmemiş olsa da).etkili bir şekilde birden fazla özelliklerine .sum() aramak

public OminitureStats GetAvgOmnitureData(int? fnsId, int dateRange) 
    { 
     IQueryable<OminitureStats> query = GetOmnitureDataAsQueryable(fnsId, dateRange); 

     int pageViews = query.Sum(q => q.PageViews); 
     int monthlyUniqueVisitors = query.Sum(q => q.MonthlyUniqueVisitors); 
     int visits = query.Sum(q => q.Visits); 
     double pagesPerVisit = (double)query.Sum(q => q.PagesPerVisit); 
     double bounceRate = (double)query.Sum(q => q.BounceRate); 

     return new OminitureStats(pageViews, monthlyUniqueVisitors, visits, bounceRate, pagesPerVisit); 
    } 

Düzenleme

private IQueryable<OminitureStats> GetOmnitureDataAsQueryable(int? fnsId, int dateRange) 
    { 
     var yesterday = DateTime.Today.AddDays(-1); 
     var nDays = yesterday.AddDays(-dateRange); 

     if (fnsId.HasValue) 
     { 
      IQueryable<OminitureStats> query = from o in lhDB.omniture_stats 
               where o.fns_id == fnsId 
                && o.date <= yesterday 
                && o.date > nDays 
               select new OminitureStats ( 
                o.page_views.GetValueOrDefault(), 
                o.monthly_unique.GetValueOrDefault(), 
                o.visits.GetValueOrDefault(), 
                (double)o.bounce_rate.GetValueOrDefault() 
               ); 
      return query; 
     } 
     return null; 
    } 

Düzenleme: IIRC

public class OminitureStats 
    { 
     public OminitureStats(int PageViews, int MonthlyUniqueVisitors, int Visits, double BounceRate) 
     { 
      this.PageViews = PageViews; 
      this.MonthlyUniqueVisitors = MonthlyUniqueVisitors; 
      this.Visits = Visits; 
      this.BounceRate = BounceRate; 
      this.PagesPerVisit = Math.Round((double)(PageViews/Visits), 1); 
     } 

     public OminitureStats(int PageViews, int MonthlyUniqueVisitors, int Visits, double BounceRate, double PagesPerVisit) 
     { 
      this.PageViews = PageViews; 
      this.MonthlyUniqueVisitors = MonthlyUniqueVisitors; 
      this.Visits = Visits; 
      this.BounceRate = BounceRate; 
      this.PagesPerVisit = PagesPerVisit; 
     } 

     public int PageViews { get; set; } 
     public int MonthlyUniqueVisitors { get; set; } 
     public int Visits { get; set; } 
     public double PagesPerVisit { get; set; } 
     public double BounceRate { get; set; } 
    } 

cevap

6

(sorgu SQL çevrilmiş olduğu sürece) tek seferde tüm toplamları yapabilirsiniz ile

var sums = query.GroupBy(q => 1) 
       .Select(g => new 
       { 
        PageViews = g.Sum(q => q.PageViews), 
        Visits = g.Sum(q => q.Visits), 
        // etc etc 
       }) 
       .Single(); 

Bu, ayrı özellikler tüm miktarda içeren bir nesne verecektir. o NotSupportedException atma neden

+0

Teşekkür Jon. Ancak "var toplamı" da "NotSupportedException" alıyorum .... ama senin çözümünle ilgisi yok. Çünkü yaptığım şeyi test ettim ve hala bu istisnayı atacaktı. 'IQueryable bölümü ile ilgisi var mı? – SherCoder

+0

Ayrıca, çözümünüz, yaptığım gibi farklı. Her bir özellikte hala .Sum() aramak zorundayım. Teşekkürler – SherCoder

+0

@SherCoder: İstisna ile ilgili olarak, ne tür bir “IQueryable” ile çalıştığınızı bize söylemeniz gerekecek. Bunun nasıl daha iyi olduğu ile ilgili olarak: tüm toplamlar aynı ifade ağacının bir parçası olarak ifade edilir, bu nedenle SQL çeviri katmanı bunları yalnızca bir sorguda çekebilir. – Jon

0

buldum. Linq to Entity'un parametreli kurucuları desteklemediğini öğrendim, Bu yüzden kurucuları sildim ve sorgumda değişiklikler yaptım. Ben acemi bir C# programcısıyım, bu yüzden çözümümün geliştirilebileceğini bana bildirin, ama şu an itibariyle iyi çalışıyor.

public class OminitureStats 
{ 
    public int PageViews { get; set; } 
    public int MonthlyUniqueVisitors { get; set; } 
    public int Visits { get; set; } 
    public double PagesPerVisit { get; set; } 
    public double BounceRate { get; set; } 
} 


private IQueryable<OminitureStats> GetOmnitureDataAsQueryable(int? fnsId, int dateRange) 
{ 
    var yesterday = DateTime.Today.AddDays(-1); 
    var nDays = yesterday.AddDays(-dateRange); 

    if (fnsId.HasValue) 
    { 
     IQueryable<OminitureStats> query = from o in lhDB.omniture_stats 
              where o.fns_id == fnsId 
               && o.date <= yesterday 
               && o.date > nDays 
              select new OminitureStats() { 
               o.page_views.GetValueOrDefault(), 
               o.monthly_unique.GetValueOrDefault(), 
               o.visits.GetValueOrDefault(), 
               (double)o.bounce_rate.GetValueOrDefault() 
              }; 
     return query; 
    } 
    return null; 
} 
İlgili konular