我是LINQ的新手,并且对一些简单的LINQ了解甚少。但是现在,我拥有的东西比我能做的更复杂。我已经创建了SQL语句,尝试了它并且它可以工作。但我无法将其转换为LINQ。
编辑:我尝试对linq进行编码并创建了一个模型,以便将其展示给视图。但是,我没有得到我想要的数据。我无法弄清楚我在哪里弄错了linq。请帮忙。
This are the tables involved, the output using SQL and output using LINQ
这是SQL:
select oh.date, oh.id,
od.TotalAmount,
CASE when oh.Discount_level = 2
then ((od.TotalAmount / 1.12) * .2)
END as Discount,
(od.TotalAmount / 1.12) as VATSale,
((od.TotalAmount / 1.12) * .12) as VAT,
CASE when oh.Discount_level = 2
then ((od.TotalAmount / 1.12) * .8)
when oh.Discount_level = 1
then od.TotalAmount
END as AmountDue
from Order_Header oh
inner join
(
select Order_Header_id, SUM(price * quantity) as TotalAmount
from Order_Details
group by Order_Header_id
) od
on oh.id = od.Order_Header_id;
我有的linq:
var list = (from oh in db.Order_Header
join iq in (
from t in db.Order_Details
group t by t.Order_Header_id
into g
select new
{
ohId = g.Key,
totalAmount = ((from t2 in db.Order_Details select t2.price * t2.quantity)).Max()
}
)
on oh.id equals iq.ohId
select new Report
{
date = oh.date,
ohId = iq.ohId,
totalAmount = iq.totalAmount,
discount = oh.Discount_level == 2 ? (iq.totalAmount /1.12) * 2 : 0 ,
VATSale = iq.totalAmount / 1.12,
VAT = (iq.totalAmount / 1.12) * .12,
amountDue = oh.Discount_level == 2 ? ((iq.totalAmount / 1.12) * .8) * 2 : iq.totalAmount
}).ToList();
报告模型:
public class Report
{
public DateTime? date { get; set; }
public int ohId { get; set; }
public double totalAmount { get; set; }
public double discount { get; set; }
public double VATSale { get; set; }
public double VAT { get; set; }
public double amountDue { get; set; }
}
答案 0 :(得分:0)
假设您的POCO模型如下:
public class Order_Header
{
public Guid Id { get; set; }
public int Discount_Level { get; set; }
public Order_Detail Order_Detail {get;set;}
}
public class Order_Detail
{
public Guid Order_Header_Id { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
public Order_Header Order_Header { get; set; }
}
并将ods
作为IDbSet<Order_Detail>
内的DbContext
个实例。
您可以将上面的查询翻译成Lambda LINQ,就像这样。
var odproj = ods.GroupBy(x => x.Order_Header_Id)
.Select(x => new { Order_Header = x.First().Order_Header,
TotalAmount = x.Sum(y => y.Price * y.Quantity)})
.Select(x => new { Order_Header = x.Order_Header,
Id = x.Order_Header.Id,
TotalAmount = x.TotalAmount,
Discount = (x.Order_Header.Discount_Level == 2 ? ((x.TotalAmount / 1.12) * 0.2) : 0),
VATSale = (x.TotalAmount / 1.12),
VAT = ((x.TotalAmount / 1.12) * 0.12),
AmountDue = ((x.Order_Header.Discount_Level == 2) ? ((x.TotalAmount / 1.12) * 0.8)
: (x.Order_Header.Discount_Level == 1 ? x.TotalAmount : 0)
)
});
<强>解释强>
首先,我们基于Order_Detail
(一个)对Order_Header
(多个)进行分组,以定义单个事务(在POS系统意义上就是这样)。分组后,我们根据订单的价格和数量“计算”总金额。总价格计算在第一个Select
中完成,它生成一个包含2个字段的匿名类,一个用于保存Order_Header
信息,另一个用于我们想要的信息。下一个Select
我们计算折扣,VATSale等 - 第一个子句中的复杂if-else。
聚苯乙烯。我还没有在EF中试过这个,我的RAM太小了,无法启动SQL Server。用谷物和盐来理解这个想法。这个问题的关键角落,我有点犹豫不决,EF是否会识别Order_Header = x.First().Order_Header
。尽管如此,使用LINQ已经足够严重,可以保证您使用OUTER JOIN
,但最终可能会被SQL执行计划程序删除。如果它过于复杂,只需制作一个STORED PROCEDURE
并拉出edmx
来映射它(等等,Code First能做到这一点吗?我真的很想知道。)