9

Linq を使用してデータベースからデータを取得する関数があり、別の関数でその関数を呼び出して、個々のプロパティごとに .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;
    }

編集:

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

2 に答える 2

15

IIRCを使用すると、すべての合計を一度に実行できます(クエリが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 つのオブジェクトが得られます。

于 2012-07-04T21:10:22.963 に答える
0

なぜそれが投げていたのかを知りましたNotSupportedExceptionLinq 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;
}
于 2012-07-06T05:24:46.113 に答える