将sql转换为linq灾难
在我的工作中,我们的主要应用程序是在n层真正成为一种东西之前很久编写的,因此,它在存储过程中处理了大量的业务逻辑 所以我们最终决定咬紧牙关,让它不那么糟糕。我的任务是将900多行的sql脚本转换为.NET exe,这是我在C#/Linq中完成的。问题是…在另一份工作的过去5-6年里,我一直在专门做Linq,所以我的SQL有些生疏,我正在转换的一些东西以前在Linq中从未尝试过,所以我遇到了一些障碍 总之,别再抱怨了 我觉得下面的sql语句有问题,因为他正在连接一个临时表和一个派生表。下面是SQL:将sql转换为linq灾难,linq,tsql,linq-to-sql,Linq,Tsql,Linq To Sql,在我的工作中,我们的主要应用程序是在n层真正成为一种东西之前很久编写的,因此,它在存储过程中处理了大量的业务逻辑 所以我们最终决定咬紧牙关,让它不那么糟糕。我的任务是将900多行的sql脚本转换为.NET exe,这是我在C#/Linq中完成的。问题是…在另一份工作的过去5-6年里,我一直在专门做Linq,所以我的SQL有些生疏,我正在转换的一些东西以前在Linq中从未尝试过,所以我遇到了一些障碍 总之,别再抱怨了 我觉得下面的sql语句有问题,因为他正在连接一个临时表和一个派生表。下面是SQL
insert into #processedBatchesPurgeList
select d.pricebatchdetailid
from pricebatchheader h (nolock)
join pricebatchstatus pbs (nolock) on h.pricebatchstatusid = pbs.pricebatchstatusid
join pricebatchdetail d (nolock) on h.pricebatchheaderid = d.pricebatchheaderid
join
( -- Grab most recent REG.
select
item_key
,store_no
,pricebatchdetailid = max(pricebatchdetailid)
from pricebatchdetail _pbd (nolock)
join pricechgtype pct (nolock) on _pbd.pricechgtypeid = pct.pricechgtypeid
where
lower(rtrim(ltrim(pct.pricechgtypedesc))) = 'reg'
and expired = 0
group by item_key, store_no
) dreg
on d.item_key = dreg.item_key
and d.store_no = dreg.store_no
where
d.pricebatchdetailid < dreg.pricebatchdetailid -- Make sure PBD is not most recent REG.
and h.processeddate < @processedBatchesPurgeDateLimit
and lower(rtrim(ltrim(pbs.pricebatchstatusdesc))) = 'processed' -- Pushed/processed batches only.
我遇到的问题是#processedBatchesPurgeList上的连接
那么,呃……帮帮忙?我从未编写过这样的SQL,当然也从未尝试将其转换为Linq。正如上面的评论所指出的,这不再被重写为Linq 他希望在实现更好的SOX合规性的同时获得性能改进,这是重写的首要原因 我很高兴能满足SOX合规性问题
谢谢大家。如果您的sql使用了许多临时表,而您无法将它们重构掉,那么存储过程可能是最好的选择。如果这是工作,它看起来像相当干净的TSQL#processedBatchesPurgeList可能很昂贵,而且它会具体化,因此以后不会在该联接中多次重新评估它。那些(诺洛克)不是偶然出现的。在你把LINQ和TSQL的性能进行比较之前,我也同意你很可能是在浪费时间来转换一些可以工作的东西,不管LINQ多么酷!重写这个脚本的原因是什么?为什么不直接从exe启动sql脚本呢?你知道这是有道理的。是的,这就是最终的结果。嗯,不是直接从exe启动sql,而是将脚本包装到存储过程中并调用它。整个项目都要归功于SOX法规遵从性,因为dba手工执行数据更改脚本是一个不可忽视的问题。谢谢大家的帮助。
var dreg = (from _pbd in db.PriceBatchDetails.Where(pbd => pbd.Expired == false && pbd.PriceChgType.PriceChgTypeDesc.ToLower().Trim() == "reg")
group _pbd by new { _pbd.Item_Key, _pbd.Store_No } into _pbds
select new
{
Item_Key = _pbds.Key.Item_Key,
Store_No = _pbds.Key.Store_No,
PriceBatchDetailID = _pbds.Max(pbdet => pbdet.PriceBatchDetailID)
});
var query = (from h in db.PriceBatchHeaders.Where(pbh => pbh.ProcessedDate < processedBatchesPurgeDateLimit)
join pbs in db.PriceBatchStatus on h.PriceBatchStatusID equals pbs.PriceBatchStatusID
join d in db.PriceBatchDetails on h.PriceBatchHeaderID equals d.PriceBatchHeaderID
join dr in dreg on new { d.Item_Key, d.Store_No } equals new { dr.Item_Key, dr.Store_No }
where d.PriceBatchDetailID < dr.PriceBatchDetailID
&& pbs.PriceBatchStatusDesc.ToLower().Trim() == "processed"
select d.PriceBatchDetailID);
insert into #pbhArchiveFullListSaved
select h.pricebatchheaderid
from pricebatchheader h (nolock)
join pricebatchdetail d (nolock)
on h.pricebatchheaderid = d.pricebatchheaderid
join #processedBatchesPurgeList dlist
on d.pricebatchdetailid = dlist.pricebatchdetailid -- PBH list is restricted to PBD purge list rows that have PBH references.
group by h.pricebatchheaderid