将sql转换为linq灾难

将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

在我的工作中,我们的主要应用程序是在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