过去三天我一直在做一项任务。我尝试将一个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 result ::
Linq结果::
我想,在我的linq查询中,我没有按小时分组!
任何人都能帮助我吗?
答案 0 :(得分: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仍然是补充工具。
答案 1 :(得分:0)
正如拉迪斯拉夫(以及我自己的经验)所说:在一个细分市场中转动比在客户方面做得更有效率。但是你可能有理由不这样做。无论如何,我想我知道问题是什么。您不应该在分组中包含小时数:
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),