2012-09-24 3 views
1

내 일에 우리의 주 응용 프로그램은 오래 전에 n 계층이 정말로 일이되기 전에 작성되었습니다. 에르고가 있습니다. 많은 톤의 비즈니스 로직이 저장된 procs 등에서 처리되기 시작합니다.SQL을 linq로 바꾸는 것

그래서 우리는 마침내 총알을 물지 않기로 결심했습니다. 나는 C#/Linq에서하고있는 .NET exe로 900+ 라인 SQL 스크립트를 변환하는 임무를 맡고있다. 문제는 ... 다른 직업에서 지난 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 구현에 로컬 시퀀스를 사용할 수 없습니다."라는 메시지가 나타납니다. 오류.

난 그냥 그렇게 하나 하나가 악몽 긴 얻을 것이다,이 쿼리를 사용하여 작동하려면 파생 된 테이블에 가입을 얻을 수있었습니다 :

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); 

그래서 쿼리는 예상 결과를 제공하는 I 목록에 있지만 그 다음에 그 쿼리의 결과를 데이터베이스에서 선택된 다른 쿼리 결과에 조인 할 필요가 있습니다. 그러면 위에서 언급 한 "로컬 시퀀스를 사용할 수 없습니다 ..."오류가 발생합니다.

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로 변환하려고 시도하지도 않았다.

+5

sql이 여러 임시 테이블을 사용하고 리팩토링 할 수없는 경우 저장된 프로 시저가 가장 좋은 옵션 일 수 있습니다. – jrummell

+1

둘째. 그것이 작동한다면 꽤 깨끗한 TSQL처럼 보입니다. #processedBatchesPurgeList는 값이 비싸고 나중에 구체화되어 여러 번 다시 조인되지 않습니다. 그 (nolock) 우연히 거기 있지 않습니다. 너무 멀리 가기 전에 LINQ의 성능을 TSQL과 비교하십시오. – Paparazzi

+0

나는 LINQ가 멋지지만 작동하는 무언가를 변환하는 데 시간을 낭비하고 있다는 것에도 동의 할 것입니다! 이 스크립트를 다시 작성한 이유는 무엇입니까? 왜 그냥 exe에서 SQL 스크립트를 해고하지? 너는 그것이 의미가 있다는 것을 안다. – Tom

답변

0

위의 설명에서 지적한대로 더 이상 Linq로 다시 작성되지 않습니다.

더 나은 SOX 준수를 달성하는 것과 함께 성능 향상을 기대했는데, 이는 처음부터 다시 쓰는 이유였습니다.

에 만족합니다.은 SOX 준수 문제를 만족합니다.

감사합니다.

관련 문제