大规模SQL查询需要转换为LINQ

时间:2013-07-21 17:16:30

标签: sql linq

我有一个SQL查询,我需要转换为LINQ。已经花了一整天的时间,没有太多的运气。这是查询

SELECT PC.PRSCLAIMID,
date_format(PC.DATEOFCLAIM, '%d/%m/%Y') as DateofClaim,
PC.PRSREFNO,
PC.FKARTISTID,
PC.FKSETLISTINFOID,
PC.STATUS,
PC.FROMDNN,
PC.EXPORTTYPE,
PC.FK_CATEGORYID,
A.LOGINNAME,
A.BANDNAME,
SMCATEGORIESTYPE.CATEGORYTYPE,
Count(SMLIVECLAIMS.LIVECLAIMSID) AS GIGCOUNT,
SMCATEGORIES.ID AS PROCESSEDID,
SMCATEGORIES.CATEGORY,
Ifnull(BC.FILENAME, '') AS BULKCLAIM_NAME
FROM SMARTISTDETAILS AS A
INNER JOIN SMPRSCLAIMS AS PC
ON A.ARTISTID = PC.FKARTISTID
INNER JOIN SMCATEGORIES
ON PC.FK_CATEGORYID = SMCATEGORIES.ID
INNER JOIN SMCATEGORIESTYPE
ON SMCATEGORIES.FK_CATEGORYTYPEID = SMCATEGORIESTYPE.ID
INNER JOIN SMPRSLIVECLAIMLINK
ON PC.PRSCLAIMID = SMPRSLIVECLAIMLINK.FKPRSCLAIMID
INNER JOIN SMLIVECLAIMS
ON SMPRSLIVECLAIMLINK.FKLIVECLAIMID = SMLIVECLAIMS.LIVECLAIMSID
LEFT OUTER JOIN BULKCLAIMDETAIL BCD
ON BCD.FKPRSCLAIMID = PC.PRSCLAIMID
LEFT OUTER JOIN BULKCLAIM BC
ON BC.ID_BULKCLAIM = BCD.ID_BULKCLAIM
WHERE ( PC.EXPORTTYPE > 0 )
AND ( A.DBID = 1 )
AND ( CASE
WHEN PC.EXPORTTYPE = 1
AND ( SMLIVECLAIMS.GIGDATE < Date_add(Now(), INTERVAL -1 YEAR) ) THEN 0
ELSE 1
END = 1 )
GROUP BY PC.PRSCLAIMID
ORDER BY PC.DATEOFCLAIM DESC

我所做的是以下转换

    from e in
        (from artistData in dbContext.smartistdetails where artistData.DbId == 1 // SessionFacade.DBId
        join smprsclaimsData in dbContext.smprsclaims on artistData.ArtistID equals smprsclaimsData.fkArtistID join smCategoriesData in dbContext.smcategories on smprsclaimsData.FK_CategoryID equals smCategoriesData.Id join smCategoriesTypeData in dbContext.smcategoriestype on smCategoriesData.fk_CategoryTypeId equals smCategoriesTypeData.Id join smPrsLiveClaimsLinkData in dbContext.smprsliveclaimlink on smprsclaimsData.PRSClaimID equals smPrsLiveClaimsLinkData.fkPRSClaimID join smLiveClaimData in dbContext.smliveclaims on smPrsLiveClaimsLinkData.fkLiveClaimID equals smLiveClaimData.LiveclaimsID join bulkClaimDetailData in dbContext.bulkclaimdetail on smprsclaimsData.PRSClaimID equals bulkClaimDetailData.fkPRSClaimID into bulkClaimDetailJoined from bulkClaimDetailJoinedData in bulkClaimDetailJoined.DefaultIfEmpty() join bulkClaimData in dbContext.bulkclaim on bulkClaimDetailJoinedData.ID_BulkClaim equals bulkClaimData.ID_BulkClaim into bulkClaimJoined from bulkClaimJoinedData in bulkClaimJoined.DefaultIfEmpty() where smprsclaimsData.ExportType > 0 select new {
            PRSCLAIMID_Inner = smprsclaimsData.PRSClaimID,
            GigDate = smLiveClaimData.GigDate,
            DateofClaim = smprsclaimsData.DateofClaim,
            PRSREFNO = smprsclaimsData.PRSRefNo,
            FKARTISTID = smprsclaimsData.fkArtistID,
            FKSETLISTINFOID = smprsclaimsData.fkSetlistInfoID,
            STATUS = smprsclaimsData.Status,
            FROMDNN = smprsclaimsData.FromDNN,
            EXPORTTYPE = smprsclaimsData.ExportType,
            FK_CATEGORYID = smprsclaimsData.FK_CategoryID,
            LOGINNAME = artistData.LoginName,
            BANDNAME = artistData.BandName,
            CATEGORYTYPE = smCategoriesTypeData.CategoryType,
            LiveclaimsID = smLiveClaimData.LiveclaimsID,
            PROCESSEDID = smCategoriesData.Id,
            CATEGORY = smCategoriesData.Category,
            BULKCLAIM_NAME = bulkClaimJoinedData.FileName == null ? "" : bulkClaimJoinedData.FileName
        })
    where!(e.EXPORTTYPE == 1 && e.GigDate < oneYearOldDate)
    group e by e.PRSCLAIMID_Inner into groupedData
    select new {
        PRSCLAIMID_Outer = groupedData.Key,
        GIGCOUNT = groupedData.Count(),
        DateofClaim = groupedData.Select(a = > a.DateofClaim).FirstOrDefault(),
        PRSREFNO = groupedData.Select(a = > a.PRSREFNO).FirstOrDefault(),
        FKARTISTID = groupedData.Select(a = > a.FKARTISTID).FirstOrDefault(),
        FKSETLISTINFOID = groupedData.Select(a = > a.FKSETLISTINFOID).FirstOrDefault(),
        STATUS = groupedData.Select(a = > a.STATUS).FirstOrDefault(),
        FROMDNN = groupedData.Select(a = > a.FROMDNN).FirstOrDefault(),
        EXPORTTYPE = groupedData.Select(a = > a.EXPORTTYPE).FirstOrDefault(),
        FK_CATEGORYID = groupedData.Select(a = > a.FK_CATEGORYID).FirstOrDefault(),
        LOGINNAME = groupedData.Select(a = > a.LOGINNAME).FirstOrDefault(),
        BANDNAME = groupedData.Select(a = > a.BANDNAME).FirstOrDefault(),
        CATEGORYTYPE = groupedData.Select(a = > a.CATEGORYTYPE).FirstOrDefault(),
        PROCESSEDID = groupedData.Select(a = > a.PROCESSEDID).FirstOrDefault(),
        CATEGORY = groupedData.Select(a = > a.CATEGORY).FirstOrDefault(),
        BULKCLAIM_NAME = groupedData.Select(a = > a.BULKCLAIM_NAME).FirstOrDefault()
    }).OrderByDescending(a = > a.DateofClaim)

此转换正在运行,但速度太慢,然后我创建了另一个转换

from smprsclaimsData in dbContext.smprsclaims
group smprsclaimsData by new { smprsclaimsData.PRSClaimID, smprsclaimsData.fkArtistID, smprsclaimsData.FK_CategoryID } into smprsclaimsGroupedData
join artistData in dbContext.smartistdetails on smprsclaimsGroupedData.Key.fkArtistID equals artistData.ArtistID
let loginName = artistData.LoginName
let bandName = artistData.BandName
join smCategoriesData in dbContext.smcategories on smprsclaimsGroupedData.Key.FK_CategoryID equals smCategoriesData.Id
join smCategoriesTypeData in dbContext.smcategoriestype on smCategoriesData.fk_CategoryTypeId equals smCategoriesTypeData.Id
join smPrsLiveClaimsLinkData in dbContext.smprsliveclaimlink on smprsclaimsGroupedData.Key.PRSClaimID equals smPrsLiveClaimsLinkData.fkPRSClaimID
join smLiveClaimData in dbContext.smliveclaims on smPrsLiveClaimsLinkData.fkLiveClaimID equals smLiveClaimData.LiveclaimsID
join bulkClaimDetailData in dbContext.bulkclaimdetail on smprsclaimsGroupedData.Key.PRSClaimID equals bulkClaimDetailData.fkPRSClaimID into bulkClaimDetailJoined
from bulkClaimDetailJoinedData in bulkClaimDetailJoined.DefaultIfEmpty()
join bulkClaimData in dbContext.bulkclaim on bulkClaimDetailJoinedData.ID_BulkClaim equals bulkClaimData.ID_BulkClaim into bulkClaimJoined
from bulkClaimJoinedData in bulkClaimJoined.DefaultIfEmpty()
where smprsclaimsGroupedData.Select(a => a.ExportType).FirstOrDefault() > 0 && artistData.DbId == 1
&& !(smprsclaimsGroupedData.Select(a => a.ExportType).FirstOrDefault() == 1 && smLiveClaimData.GigDate < oneYearOldDate)
select new
{
PRSCLAIMID_Inner = 1,
GigDate = smLiveClaimData.GigDate,
DateofClaim = smprsclaimsGroupedData.Select(a => a.DateofClaim),
PRSREFNO = smprsclaimsGroupedData.Select(a => a.PRSRefNo),
FKARTISTID = smprsclaimsGroupedData.Select(a => a.fkArtistID),
FKSETLISTINFOID = smprsclaimsGroupedData.Select(a => a.fkSetlistInfoID),
STATUS = smprsclaimsGroupedData.Select(a => a.Status),
FROMDNN = smprsclaimsGroupedData.Select(a => a.FromDNN),
EXPORTTYPE = smprsclaimsGroupedData.Select(a => a.ExportType),
FK_CATEGORYID = smprsclaimsGroupedData.Select(a => a.FK_CategoryID),
LOGINNAME = loginName,
BANDNAME = bandName,
CATEGORYTYPE = smCategoriesTypeData.CategoryType,
//GIGCOUNT = smprsclaimsGroupedData.Count(),
PROCESSEDID = smCategoriesData.Id,
CATEGORY = smCategoriesData.Category,
BULKCLAIM_NAME = bulkClaimJoinedData.FileName == null ? "" : bulkClaimJoinedData.FileName,
})

这个查询没有获取预期的数据,我认为这是由于多个(分组依据)。我也无法发布我的数据库架构,这个问题已经太长了,无法阅读。有关如何绕过或解决此转换的任何帮助或任何建议。

1 个答案:

答案 0 :(得分:1)

我认为你过度思考LINQ了,试试以下LINQ。我唯一不确定的是GIGCOUNT结果,因此可能需要一些摆弄。

(
from A in SMARTISTDETAILS

join PC in SMPRSCLAIMS on A.ARTISTID equals PC.FKARTISTID
join categories in SMCATEGORIES on PC.FK_CATEGORYID equals categories.ID
join categoryType in SMCATEGORIESTYPE on categories.FK_CATEGORYTYPEID equals categoryType.ID
join link in SMPRSLIVECLAIMLINK on PC.PRSCLAIMID equals link.FKPRSCLAIMID
join liveClaims in SMLIVECLAIMS on link.FKLIVECLAIMID equals liveClaims.LIVECLAIMSID

join bulkDetail in BULKCLAIMDETAIL on PC.PRSCLAIMID equals bulkDetail.FKPRSCLAIMID into BULK_DETAILS
from BCD in BULK_DETAILS.DefaultIfEmpty()

join bulkClaim in BULKCLAIM on BCD.ID_BULKCLAIM equals bulkClaim.ID_BULKCLAIM into BULK_CLAIMS
from BC in BULK_CLAIMS.DefaultIfEmpty()

where
   ( PC.EXPORTTYPE > 0 )
   && ( A.DBID == 1 )
   && (
      PC.EXPORTTYPE == 1 && liveClaims.GIGDATE < DateTime.Now.AddYears(-1) ? 0 : 1
   ) == 1

orderby PC.DATEOFCLAIM descending

select new
{
   PC.PRSCLAIMID,
   DateofClaim = PC.DATEOFCLAIM,
   PC.PRSREFNO,
   PC.FKARTISTID,
   PC.FKLISTINFOID,
   PC.STATUS,
   PC.FROMDNN,
   PC.EXPORTTYPE,
   PC.FK_CATEGORYID,
   A.LOGINNAME,
   A.BANDNAME,
   categoryType.CATEGORYTYPE,

   // This gets me the correct count now
   GIGCOUNT = SMPRSLIVECLAIMLINK.Where(LINK => LINK.FKPRSCLAIMID == PC.PRSCLAIMID && (PC.EXPORTTYPE == 1 && LINK.FKLIVECLAIMIDSMLIVECLAIMS.GIGDATE < DateTime.Now.AddYears(-1) ? 0 : 1) == 1).Count(),

   PROCESSEDID = categories.ID,
   categories.CATEGORY,
   BULKCLAIM_NAME = BC.FILENAME ?? String.Empty
})
// Use distinct to get rid of duplicate rows
.Distinct()
.ToList()
.GroupBy(o => 
   o.PRSCLAIMID
)

编辑:

我改变了计算GIGCOUNT属性的方式,现在应该返回正确的数字。您还需要使用Distinct()扩展名,以便删除重复的行。