내 일에 우리의 주 응용 프로그램은 오래 전에 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로 변환하려고 시도하지도 않았다.
sql이 여러 임시 테이블을 사용하고 리팩토링 할 수없는 경우 저장된 프로 시저가 가장 좋은 옵션 일 수 있습니다. – jrummell
둘째. 그것이 작동한다면 꽤 깨끗한 TSQL처럼 보입니다. #processedBatchesPurgeList는 값이 비싸고 나중에 구체화되어 여러 번 다시 조인되지 않습니다. 그 (nolock) 우연히 거기 있지 않습니다. 너무 멀리 가기 전에 LINQ의 성능을 TSQL과 비교하십시오. – Paparazzi
나는 LINQ가 멋지지만 작동하는 무언가를 변환하는 데 시간을 낭비하고 있다는 것에도 동의 할 것입니다! 이 스크립트를 다시 작성한 이유는 무엇입니까? 왜 그냥 exe에서 SQL 스크립트를 해고하지? 너는 그것이 의미가 있다는 것을 안다. – Tom