2011-07-25 17 views
0

私は新しいエンティティフレームワークを使いこなしています。ちょうど楽しみのために、以前のサイトのすべてのquerysを新しいサイトやshinny linqに変換したかったのです。しかし、私は本当にこのクエリを把握できません。最小の助けは素晴らしいだろう。SQLをLinqに変換する

私は、それはそれを残している場合、それは入れ子の選択よりであり、その中のSO ..今、私の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

なぜあなたはそれを変更する必要がありますか?複数のツールを使用することはOKです...もしLINQ/EFがそれを難し​​くするなら、それをIMOに使用しないでください。特にレポートクエリのように見える場合は、おそらく完全なORMは必要ありません。もっと単純なものを使うことを考えましたか?未使用のADO.NET? "dapper"のようなMicro-ORM?私はすべてを意味するものではありません - 私はちょうどこの既存のTSQLを動作させることを意味しています... –

答えて

0

このようなものです。

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

あなたはあなたがLINQを学び、あなたのLINQの式が正しいかどうか確認してください助けることができるLINQPadを見ることができます。);これは、あなたがより効果的なLINQを理解するのに役立つことを願っています。