0

私は過去 3 日間から 1 つのタスクを実行しています。1つのSQLクエリを、ピボットテーブルと呼ばれる「列を行に変換」に基づくlinqに変換しようとしています。

私のSQLクエリは以下の通りです。

SELECT project_name
,SUNDAY
,MONDAY
,TUESDAY
,WEDNESDAY
,THRUSDAY
,FRIDAY
,SATURDAY
FROM
(
    SELECT project_name
    ,personnel_name
    ,DATENAME(dw, report_date) AS day_name
    ,SUM(hours) AS HOURS
    FROM [TimeSheet]

    INNER JOIN [ProjectMaster] 
    ON [TimeSheet].[project_id] = [ProjectMaster].[project_id]

    INNER JOIN [Personnel] 
    ON [TimeSheet].[personnel_id] = [Personnel].[personnel_id]
    WHERE report_date BETWEEN getdate() - 7 AND getdate()
    GROUP BY project_name, personnel_name, DATENAME(dw, report_date)
) sourceQuery PIVOT (SUM(hours) 
 FOR day_name IN 
 (SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THRUSDAY,FRIDAY,SATURDAY)) AS pvt

これまでのところ、それをlinqに変換することは以下のとおりです!!!

var before = DateTime.Now.AddDays(-7);
DateTime firstSunday = new DateTime(1753, 1, 7); 

var DayWiseTS = from TSList in objWPFEntities.Timesheets.Include("ProjectMaster").Include("Personnel")
where (TSList.report_date >= before && TSList.report_date <= System.DateTime.Now)
select new { TSList.ProjectMaster.project_name, TSList.Personnel.personnel_name, TSList.report_date, TSList.hours } into sourceQuery
group sourceQuery by new { sourceQuery.project_name, sourceQuery.personnel_name, sourceQuery.report_date, sourceQuery.hours } into pvt
select new 
{ 
projectname = pvt.Key.project_name,
Sunday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 0 ? pvt.Sum(g => g.hours) : 0),
Monday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 1 ? pvt.Sum(g => g.hours) : 0),
Tuesday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 2 ? pvt.Sum(g => g.hours) : 0),
Wednesday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 3 ? pvt.Sum(g => g.hours) : 0),
Thrusday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 4 ? pvt.Sum(g => g.hours) : 0),
Friday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 5 ? pvt.Sum(g => g.hours) : 0),
Saturday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7 == 6 ? pvt.Sum(g => g.hours) : 0)
};

両方のクエリで結果が得られましたが、SQLでは必要に応じて完璧な結果が得られましたが、linqでは必要なデータをSQLとして取得していません。

SQL結果::

ここに画像の説明を入力

Linq の結果 ::

ここに画像の説明を入力

私のlinqクエリでは、時間ごとにグループ化できなかったと思います!!

誰でもこれで私を助けることができますか??

4

2 に答える 2

1

あきらめる。EF には、ピボット クエリを実行するためのツール セットがありません。たとえ何とかそれを実行できたとしても、クエリのパフォーマンスはひどいものになります。SQL クエリを Linq クエリに変換する代わりに、クエリの結果セットと同じ名前のプロパティを持つクラスを作成するだけです。

public class HoursPerDay {
    // if you want different names you must use aliases in your query too
    public string project_name { get; set; } 
    public int SUNDAY { get; set; }
    public int MONDAY { get; set; }
    public int TUESDAY { get; set; }
    public int WEDNESDAY { get; set; }
    public int THURSDAY { get; set; }
    public int FRIDAY { get; set; }
    public int SATURDAY { get; set; }
}

objectContext.ExecuteStoreQueryまたはを使用しますdbContext.Database.SqlQuery

var data = dbContext.Database.SqlQuery<HoursPerDay>(yourSqlQuery);

簡単な結論として、Linq-to-entities は最終的に SQL に取って代わるものではありません。Entity Framework を使用する場合、SQL は依然として補完的なツールです。

于 2012-10-05T06:43:26.230 に答える
0

Ladislav (および私自身の経験) が言うように、sproc でのピボットは、クライアント側で行うよりもはるかに効率的です。しかし、そうしない理由があるかもしれません。とにかく、私は問題が何であるかを知っていると思います。グループ化に時間を含めないでください。

group sourceQuery by new { sourceQuery.project_name, sourceQuery.personnel_name,
                           sourceQuery.report_date } into pvt

結果セットのステートメントは同じままです。

...
Sunday = (EntityFunctions.DiffDays(firstSunday, pvt.Key.report_date.Value) % 7
         == 0 ? pvt.Sum(g => g.hours) : 0),
于 2012-10-05T18:16:10.907 に答える