我有一个对我来说真的很复杂的SQL查询,我试图将其转换为基于EntityFramework Core的代码,但我至少不能执行多重连接。
SELECT vrCore_Product.iMasterId, vrCore_Product.sName[Particular],
SUM(tCore_Indta_0.fQuantityInBase) - ISNULL(AVG(tCore_ReservedStock_0.fQuantity),0)[Net Quantity],vrPos_Outlet.iMasterId[Product]
,vrCore_Product.sCode[vrCore_Product.sCode0] FROM tCore_Data_0
JOIN tCore_Header_0 ON tCore_Header_0.iHeaderId = tCore_Data_0.iHeaderId
JOIN tCore_Indta_0 ON tCore_Data_0.iBodyId = tCore_Indta_0.iBodyId
JOIN cCore_Vouchers_0 WITH (READUNCOMMITTED) ON tCore_Header_0.iVoucherType = cCore_Vouchers_0.iVoucherType
JOIN vrCore_Product ON vrCore_Product.iMasterId = tCore_Indta_0.iProduct AND vrCore_Product.iTreeId = 0
JOIN vrPos_Outlet ON vrPos_Outlet.iMasterId = tCore_Data_0.iInvTag
LEFT JOIN
(
Select iProduct, tCore_Data_0.iInvTag, SUM(case bReserveOrRelease when 0 then tCore_ReservedStock_0.fQuantity else -tCore_ReservedStock_0.fQuantity end) fQuantity
FROM tCore_ReservedStock_0
JOIN tCore_Data_0 ON tCore_Data_0.iTransactionId = tCore_ReservedStock_0.iTransactionId
JOIN tCore_Indta_0 ON tCore_Indta_0.iBodyId = tCore_Data_0.iBodyId
JOIN tCore_Header_0 ON tCore_Header_0.iHeaderId = tCore_Data_0.iHeaderId
WHERE tCore_Header_0.bSuspended = 0
GROUP BY iProduct,tCore_Data_0.iInvTag
HAVING SUM(CASE bReserveOrRelease WHEN 0 THEN tCore_ReservedStock_0.fQuantity ELSE -tCore_ReservedStock_0.fQuantity END)<>0
)tCore_ReservedStock_0 ON tCore_ReservedStock_0.iProduct = tCore_Indta_0.iProduct AND tCore_ReservedStock_0.iInvTag = tCore_Data_0.iInvTag WHERE tCore_Header_0.bUpdateStocks = 1 AND tCore_Data_0.bSuspendUpdateStocks <> 1
AND tCore_Header_0.bSuspended = 0 AND tCore_Data_0.iAuthStatus < 2
AND (tCore_Header_0.iDate BETWEEN dbo.DateToInt('2020-01-10') AND dbo.DateToInt('2020-01-22') OR (tCore_Header_0.iDate < dbo.DateToInt('2020-01-22') AND tCore_Header_0.iVoucherClass = 512)) AND vrCore_Product.iProductType <> 'Service' AND vrPos_Outlet.iMasterId IN (26) GROUP BY vrPos_Outlet.iMasterId, vrCore_Product.iMasterId, vrCore_Product.sName ,vrCore_Product.sCode HAVING SUM(tCore_Indta_0.fQuantity) <> 0 ORDER BY vrPos_Outlet.iMasterId
答案 0 :(得分:1)
使用C#进行编码时,我们会考虑对象。在执行T-SQL时,我们认为是关系型的。这产生了一个称为对象关系阻抗失配的问题。 EF通过允许我们仅在对象中进行思考来帮助解决该问题。您正试图做完全相反的事情,即通过Linq查询将查询转换回对象表示形式。提示:我从不那样做。我的起点是C#对象模型,我在Linq中对查询思维进行建模。我不在乎T-SQL。
这似乎只是语法问题,因为T-SQL和Linq都是查询语言,最后,EF将Linq转换为T-SQL。但是,它们之间的区别不仅在于语法,还在于我们的思维方式。例如,在考虑T-SQL中的联接时,在linq中,我们考虑了导航属性。一方面,我们考虑关系和外键,另一方面,我们考虑对象和图形。
在非常少见的情况下,我最好使用T-SQL查询,我宁愿执行原始查询,也不必经历将其转换回Linq的痛苦:https://docs.microsoft.com/en-us/ef/core/querying/raw-sql
在您的情况下,我将执行以下两项操作之一:
答案 1 :(得分:-1)
如果您有关系,则可以像这样使用Include()
var data = _context.TcoreData0
.Include(x => x.TcoreHeader0)
.Include(x => x.TcoreIndta0)
.Include("tCore_Header_0.cCore_Vouchers_0")
.Include...