2011-07-25 125 views
0

我在玩弄新的實體框架,只是爲了好玩io想把所有現存的查詢都轉換成新的和靈巧的linq。但我不能真正把這個問題看出來。最小的幫助將會是令人厭惡的。將SQL轉換爲Linq

查詢我嘗試轉換。現在可以處理在我的C#代碼的foreach所以如果離開了這一點,它更多的是嵌套的選擇,並在被竊聽我

DECLARE @Begin DateTime, @End DateTime, @date DateTime, @partnerId int 

Set @partnerId = 1 
Set @Begin = Cast('2010-01-01' as DateTime) 
Set @End = Cast(Dateadd(month, 17, @Begin) as DateTime) 
Set @date = @Begin 

SET NOCOUNT ON 
WHILE (@date <= @End) 
BEGIN 
    SELECT 
     [PackageId], 
     @date AS [Date], 
     [Name], 
     (ISNULL((SELECT [ReportId] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [ReportId], 
     (ISNULL((SELECT [UnitsForecast] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [UnitsForecast], 
     (ISNULL((SELECT [UnitsActual] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [UnitsActual], 
     (ISNULL((SELECT [RevenueForecast] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [RevenueForecast], 
     (ISNULL((SELECT [RevenueActual] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [RevenueActual], 
     (ISNULL((SELECT [UnitsInStock] FROM [Uniferon_Reports] WHERE [FK_PartnerId] = @partnerId AND [FK_PackageId] = [Uniferon_Packages].[PackageId] AND [Date] = @date), 0)) AS [UnitsInStock] 
     FROM 
      [Uniferon_Packages][Uniferon_Packages] 
     WHERE 
     [PackageId] IN 
     (SELECT [FK_PackageId] FROM [Uniferon_Partners_Packages_Relation] WHERE [FK_PartnerId] = @partnerId AND [StartDate] <= @date AND ([EndDate] >= @date OR [EndDate] IS NULL)) 


Set @date = DateAdd(month, 1, @date) 
END 
SET NOCOUNT OFF 

任何想法?

+0

爲什麼你需要改變它?使用多個工具是可以的......如果LINQ/EF很難做到......不要使用它們,IMO。尤其是在看起來像報告查詢的情況下,您可能不需要完整的ORM。你有沒有考慮過使用簡單的東西?原始的ADO.NET? Micro-ORM如「dapper」?我不是故意的 - 我的意思是運行這個現有的和可用的TSQL ... –

回答

0

就是這樣。希望這將幫助你瞭解LINQ更有效):

while (date <= endDate) 
{ 
    var result = Uniferon_Packages 
     .Where(i => 
      Uniferon_Partners_Packages_Relation.Any(rel => rel.FK_PartnerId == i.PackageId) && 
      rel.StartDate <= date && (!rel.EndDate.HasValue || rel.EndDate >= date)) 
     .Select(i => new 
         { 
          i.PackageId, 
          i.Name, 
          Date = date, 
          ReportId = GetReportId(i, partnerId, date) 
          // etc... 
         }); 

    date = date.AddMonths(1); 
} 


private int GetReportId(Uniferon_Package pack, int partnerId, DateTime date) 
{ 
    var report = Uniferon_Reports.FirstOrDefault(x => 
     x.FK_PartnerId == partnerId && 
     x.FK_PackageId == pack.PackageId && 
     x.Date == date); 

    return report != null 
     ? report.ReportId 
     : 0; 
} 
1

有一種工具叫做Linqer,它可以把你的SQL語句轉換成lamba函數。試一試,看看它能產生什麼。

0

我認爲首先要做的就是嘗試理解原始SQL - 然後您可以看看在Linq中編寫查詢。

簡單看看它,它在我看來像原始查詢的SELECT本身可能是一個寫得不好的外連接?這可能是值得一看的...

但是,請記住,如果WHILE在SQL中真正需要,那麼您可能無法將其有效地移植到客戶端C#代碼 - 如果需要在數據庫上進行循環,那麼將這些代碼留在服務器端SQL中可能會更優化。

+0

你對左外連接是如此正確。但我不能看到我應該如何得到與現在相同的值,因爲即使它沒有「值」,我也得到了這一行,這就是我需要的原因,因爲用戶需要將值放入。 – pumpin

+0

對不起 - 但是那句話對我沒有意義 – Stuart

0

你可以看一下LINQPad,可以幫助你學習LINQ和檢查你的LINQ表達正確與否。