1

在我的工作中,我们的主要应用程序是很久以前编写的,在 n 层真正成为一个东西之前,ergo - 它有大量的业务逻辑开始在存储过程等中处理。

所以我们最终决定硬着头皮让它不那么糟糕。我的任务是将 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.

所以这首先提出了一个整体问题:如何在 Linq 中处理临时表?这个脚本使用了大约 10 个。我目前将它们作为列表。问题是,如果我尝试在一个查询中使用 .Join(),我会得到“本地序列不能在 LINQ to SQL 的查询运算符中使用,但包含运算符除外。” 错误。

我能够使用 2 个查询来连接派生表,这样一个查询就不会变得像噩梦一样长:

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

#processedBatchesPurgeList 上的加入是我遇到的问题。

所以呃……救命?我从来没有写过这样的 SQL,当然也从来没有尝试将它转换为 Linq。

4

1 回答 1

0

正如上面的评论所指出的,这不再被重写为 Linq。

希望在实现更好的 SOX 合规性的同时获得性能改进,这就是重写的全部原因。

我对满足 SOX 合规性问题感到满意

谢谢大家。

于 2012-09-26T20:17:51.230 回答