我有以下查询在LINQ to SQL中正常工作。现在我想将其更改为Entity Framework
var _sale = from emp in setupEmployees
join sales in vwSaleTargets on emp.EmployeeID equals sales.EmployeeID
join price in vwPeriodPricings
on new { sales.SKUID, sales.PeriodID }
equals new { SKUID = (int?)price.SKUID, PeriodID = (int?)price.PeriodID }
join sk in setupSKUs on sales.SKUID equals sk.SKUID
join br in setupBrands on sk.BrandID equals br.BrandID
where emp.EmployeeID == 123 && sales.StartDate.Year == 2012
select new { emp, sales, price, sk, br };
var lstSale = _sale.ToList(); //to avoid n+1 queries in case of grouping
var sale2 = from x in lstSale
group x by new { x.sk, x.emp } into grouping
select new
{
EmployeeName = grouping.Key.emp.EmployeeName,
SKUID = grouping.Key.sk.SKUID,
SKUName = grouping.Key.sk.Title,
MonthSale =(double?)grouping
.Where(x => x.sales.StartDate.Month == 2 &&
x.sales.StartDate.Year == 2012)
.Select(t=>t.sales.SalesQuantity)
.Sum(t=>t.Value)?? 0,
MonthSaleValue = (double?)grouping
.Where(x => x.sales.StartDate.Month == 2 &&
x.sales.StartDate.Year == 2012)
.Sum(x => x.sales.SalesQuantity * x.price.ExFactoryPrice)
?? 0,
};
Console.WriteLine(sale2.OrderBy(x => x.SKUName).ToList());
在实体框架中它给我结果像这样
Name SKUID SKUName MonthSale MonthSaleValue
EMP1 36 SKU1 113 61375.95
EMP1 17 SKU2 113 6656.83
EMP1 18 SKU3 113 9984.68
EMP1 19 SKU4 113 15169.12
在L2S中我得到了正确的结果
Name SKUID SKUName MonthSale MonthSaleValue
EMP1 36 SKU1 74 40193.1
EMP1 17 SKU2 113 6656.83
EMP1 18 SKU3 461 40733.96
EMP1 19 SKU4 2 268.48
此致
答案 0 :(得分:5)
作为寻找答案的方法......
要诊断,正如@Jon Skeet所建议的那样,你需要简化它并查看你在lstSale中获得的内容,以便将LINQ to SQL与EntityFramework进行比较。
以下几行中的内容可能有所帮助(不一定在语法上正确,因为我没有检查所有的源对象,但是我只是查看查询并将其简化为可能的位置)
var _sale = from emp in setupEmployees
join sales in vwSaleTargets on emp.EmployeeID equals sales.EmployeeID
join price in vwPeriodPricings
on new { sales.SKUID, sales.PeriodID }
equals new { SKUID = (int?)price.SKUID, PeriodID = (int?)price.PeriodID }
join sk in setupSKUs on sales.SKUID equals sk.SKUID
where emp.EmployeeID == 123 && sales.StartDate.Year == 2012 && sales.StartDate.Month == 2
select new
{
EmployeeName = emp.EmployeeName,
StartDate = sales.StartDate,
SalesQuantity = sales.SalesQuantity,
ExFactoryPrice = price.ExFactoryPrice,
SKUID = sk.SKUID,
SKUName = sk.SKUName
};
var lstSale = _sale.ToList(); //to avoid n+1 queries in case of grouping
// Run through lstSale here
foreach(var item in lstSale)
{
Console.WriteLine(item);
}
var sale2 = from x in lstSale
group x by new { x.SKUID, x.EmployeeName } into grouping
select new
{
EmployeeName = grouping.Key.EmployeeName,
SKUID = grouping.Key.SKUID,
SKUName = grouping.SKUName,
MonthSale =(double?)grouping
.Where(x => x.StartDate.Month == 2 &&
x.StartDate.Year == 2012)
.Select(t=>t.SalesQuantity)
.Sum(t=>t.Value)?? 0,
MonthSaleValue = (double?)grouping
.Where(x => x.StartDate.Month == 2 &&
x.StartDate.Year == 2012)
.Sum(x => x.SalesQuantity * x.ExFactoryPrice)
?? 0,
};
Console.WriteLine(sale2.OrderBy(x => x.SKUName).ToList());
变更(可能并非全部有效):
1.删除品牌,因为它没有在第二个查询中使用(您可以在第一个查询中将其用作连接,但如果它的部分限制则不添加到新类型)
2.简化第一个查询生成的匿名类型中包含的内容 - 如果您只消耗了emp / sales / price的部分内容,那么它可以更清楚地说明发生了什么
3.在第一部分中添加了对SalesMonth的限制(你在第二部分中做了什么)因为这可能会减少你的数据,提高性能并让你专注于实际出错的地方(我已经保留了第二个SalesMonth限制)
4.我假设SKUID是sk用于分组的相关部分,并非所有对象都是必需的
答案 1 :(得分:0)
首先调查var lstSale = _sale.ToList();
如果是Linq-To-SQL,您可以使用:
context.Log = Console.Out;
如果是EntityFramework ObjectContext API,您可以使用
Console.WriteLine(((ObjectQuery)_sale).ToTraceString());
或DbContext API
Console.WriteLine(_sale.ToString());
如果没有挖掘SQL命令,那么提供程序处理Linq查询的方式会有所不同。