1

私の仕事では、私たちのメイン アプリケーションは、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 個を使用します。私は現在それらをリストとして持っています。問題は、クエリで .Join() を実行しようとすると、「ローカル シーケンスは、Contains 演算子以外のクエリ演算子の 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 に答える