将sql转换为linq的问题

时间:2012-09-24 14:22:48

标签: 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.

首先提出一个整体问题:如何处理Linq中的临时表?该脚本使用其中的大约10个。我目前把它们作为List。问题是,如果我在查询中尝试.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);

这样查询给出了我在List中保存的预期结果,但后来我需要将该查询的结果加入到从数据库中选择的另一个结果,这导致我回到前面提到的“本地序列不能使用......“错误。

该查询是这样的:

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。

1 个答案:

答案 0 :(得分:0)

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

希望获得性能提升以及实现更好的SOX合规性,这是首先重写的全部原因。

我很高兴只是满足SOX合规性问题。

谢谢大家。