2012-07-04 21 views
5

私はLinqを使ってデータベースからデータを取得し、その関数を別の関数で呼び出して、個々のプロパティごとに.Sumを使ってすべての個々のプロパティを合計します。私は個々のプロパティごとに.Sum()を呼び出すのではなく、一度にすべてのプロパティを合計する効率的な方法があるのだろうかと思っていました。私は今現在行っているやり方は、(テストされていないが)非常に遅いと思う。複数のプロパティで.Sum()を呼び出す効率的な方法

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

編集

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

編集: 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; } 
    } 

答えて

6

(クエリがSQLに変換されている限り)あなたは一度のすべての合計を行うことができますと

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

これは、すべての合計を別々のプロパティとして含む1つのオブジェクトを提供します。

+0

ありがとうございます。しかし、私は 'var sums ...'で 'NotSupportedException'を取得しています。あなたのソリューションとは何の関係もありません。私はそれをやっている方法をテストしたので、まだこの例外がスローされます。 'IQueryable 'の部分と関係がありますか? – SherCoder

+0

また、あなたのソリューションは私のやり方とどう違うのですか?私はまだ個々のプロパティで.Sum()を呼び出さなければなりません。ありがとうございます。 – SherCoder

+0

@SherCoder:例外に関して、あなたが働いている 'IQueryable 'の種類を正確に教えてください。これがより良い方法については、すべての合計が同じ式ツリーの一部として表現されるため、SQL変換レイヤーはただ1つのクエリでそれらを取り除くことができます。 – Jon

0

なぜそれがNotSupportedExceptionを投げているのか分かりました。 Linq to Entityはパラメータ付きのコンストラクタをサポートしていないことがわかったので、コンストラクタが削除され、クエリが変更されました。私は初心者のC#プログラマーですので、私のソリューションが改善できるかどうかを教えてください。しかし、今のところうまくいきます。

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; 
} 
関連する問題