1

LEFTではなくINNERJOINが生成される理由と、LEFTJOINビューを追加するだけでなく結合前にビュー全体が選択される理由を知りたいです。

複数のテーブルにまたがる情報のテーブルを投稿しようとしています。基本的に、日付で検索し、今日、昨日、今月に発生したイベントのすべての情報を返したいと思います。ユーザーが選択したものは何でもです。クエリはかなり長いです。LEFT JOINを取得するために、メインテーブルを除くすべてのテーブルにDefaultIfEmptyを追加しましたが、混乱しました。

using (TransitEntities t = new TransitEntities())
   {
   var charters = from c in t.tblCharters
join v in t.tblChartVehicles.DefaultIfEmpty()
on c.Veh
equals v.ChartVehID
join n in t.tblNACharters.DefaultIfEmpty()
on c.Dpt.Substring(c.Dpt.Length - 1)
equals SqlFunctions.StringConvert((double)n.NAID)
join r in t.tblChartReqs.DefaultIfEmpty()
on c.ChartReqID
equals r.ChartReqID
join f in t.tblCharterCustomers.DefaultIfEmpty()
on c.Dpt
equals (f.DptID == "NONAFF" ? SqlFunctions.StringConvert((double)f.CustID) : f.DptID)
join d in t.tblChartReqDocs.DefaultIfEmpty()
on c.Attach
equals SqlFunctions.StringConvert((double)d.DocID)
join s in t.tblChartSupAttaches.DefaultIfEmpty()
on c.SupAttach
equals SqlFunctions.StringConvert((double)s.DocID)
join p in (from e in t.v_EmpData select new {e.UIN, e.First, e.Last}).DefaultIfEmpty()
on c.TakenUIN
equals p.UIN
where c.BeginTime > EntityFunctions.AddYears(DateTime.Now,-1)
select new
{
   ChartID = c.ChartID,
   Status = c.Status,
     ...
   Website = r.Website,
};
//select today's events
gvCharters.DataSource = charters.Where(row => (row.BeginTime.Value >= midnight && row.BeginTime.Value < midnight1));

これにより、非常に複雑なSQLが生成されます。

    SELECT 
    [Extent1].[ChartID] AS [ChartID], 
    [Extent1].[Status] AS [Status], 
    ... 
    [Join5].[Website] AS [Website], 

    FROM        [dbo].[tblCharters] AS [Extent1]
    INNER JOIN  (SELECT [Extent2].[ChartVehID] AS [ChartVehID], [Extent2].[Descr] AS [Descr]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
        LEFT OUTER JOIN [dbo].[tblChartVehicles] AS [Extent2] ON 1 = 1 ) AS [Join1] ON ([Extent1].[Veh] = [Join1].[ChartVehID]) OR (([Extent1].[Veh] IS NULL) AND ([Join1].[ChartVehID] IS NULL))
    INNER JOIN  (SELECT [Extent3].[NAID] AS [NAID], [Extent3].[Descr] AS [Descr]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable2]
        LEFT OUTER JOIN [dbo].[tblNACharter] AS [Extent3] ON 1 = 1 ) AS [Join3] ON ((SUBSTRING([Extent1].[Dpt], ((LEN([Extent1].[Dpt])) - 1) + 1, (LEN([Extent1].[Dpt])) - ((LEN([Extent1].[Dpt])) - 1))) = (STR( CAST( [Join3].[NAID] AS float)))) OR ((SUBSTRING([Extent1].[Dpt], ((LEN([Extent1].[Dpt])) - 1) + 1, (LEN([Extent1].[Dpt])) - ((LEN([Extent1].[Dpt])) - 1)) IS NULL) AND (STR( CAST( [Join3].[NAID] AS float)) IS NULL))
    INNER JOIN  (SELECT [Extent4].[ChartReqID] AS [ChartReqID], [Extent4].[Event] AS [Event], [Extent4].[ContactName] AS [ContactName], [Extent4].[ContactPhone] AS [ContactPhone], [Extent4].[Website] AS [Website]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable3]
        LEFT OUTER JOIN [dbo].[tblChartReq] AS [Extent4] ON 1 = 1 ) AS [Join5] ON ([Extent1].[ChartReqID] = [Join5].[ChartReqID]) OR (([Extent1].[ChartReqID] IS NULL) AND ([Join5].[ChartReqID] IS NULL))
    INNER JOIN  (SELECT [Extent5].[CustID] AS [CustID], [Extent5].[Dpt] AS [Dpt], [Extent5].[DptID] AS [DptID]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable4]
        LEFT OUTER JOIN [dbo].[tblCharterCustomers] AS [Extent5] ON 1 = 1 ) AS [Join7] ON ([Extent1].[Dpt] = (CASE WHEN (N'NONAFF' = [Join7].[DptID]) THEN STR( CAST( [Join7].[CustID] AS float)) ELSE [Join7].[DptID] END)) OR (([Extent1].[Dpt] IS NULL) AND (CASE WHEN (N'NONAFF' = [Join7].[DptID]) THEN STR( CAST( [Join7].[CustID] AS float)) ELSE [Join7].[DptID] END IS NULL))
    INNER JOIN  (SELECT [Extent6].[DocID] AS [DocID], [Extent6].[FileName] AS [FileName]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable5]
        LEFT OUTER JOIN [dbo].[tblChartReqDocs] AS [Extent6] ON 1 = 1 ) AS [Join9] ON ([Extent1].[Attach] = (STR( CAST( [Join9].[DocID] AS float)))) OR (([Extent1].[Attach] IS NULL) AND (STR( CAST( [Join9].[DocID] AS float)) IS NULL))
    INNER JOIN  (SELECT [Extent7].[DocID] AS [DocID], [Extent7].[FileName] AS [FileName]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable6]
        LEFT OUTER JOIN [dbo].[tblChartSupAttach] AS [Extent7] ON 1 = 1 ) AS [Join11] ON ([Extent1].[SupAttach] = (STR( CAST( [Join11].[DocID] AS float)))) OR (([Extent1].[SupAttach] IS NULL) AND (STR( CAST( [Join11].[DocID] AS float)) IS NULL))
    INNER JOIN  (SELECT [Extent8].[First] AS [First], [Extent8].[Last] AS [Last], [Extent8].[UIN] AS [UIN]
        FROM   ( SELECT 1 AS X ) AS [SingleRowTable7]
        LEFT OUTER JOIN (SELECT 
          [v_EmpData].[First] AS [First], 
          [v_EmpData].[Last] AS [Last], 
          [v_EmpData].[Legal] AS [Legal], 
          [v_EmpData].[Name] AS [Name], 
          [v_EmpData].[Email] AS [Email], 
          [v_EmpData].[UIN] AS [UIN], 
          [v_EmpData].[UserNM] AS [UserNM], 
          [v_EmpData].[Worker] AS [Worker], 
          [v_EmpData].[SUPERVISORNUM] AS [SUPERVISORNUM], 
          [v_EmpData].[Supervisor] AS [Supervisor], 
          [v_EmpData].[EmpArea] AS [EmpArea], 
          [v_EmpData].[Title] AS [Title], 
          [v_EmpData].[FullName] AS [FullName], 
          [v_EmpData].[HireDate] AS [HireDate], 
          [v_EmpData].[WORKERTYPENM] AS [WORKERTYPENM], 
          [v_EmpData].[Birth] AS [Birth], 
          [v_EmpData].[HOMESTREET] AS [HOMESTREET], 
          [v_EmpData].[HOMECITY] AS [HOMECITY], 
          [v_EmpData].[HOMEZIP] AS [HOMEZIP], 
          [v_EmpData].[HOMESTATE] AS [HOMESTATE], 
          [v_EmpData].[PicID] AS [PicID], 
          [v_EmpData].[WorkPhone] AS [WorkPhone], 
          [v_EmpData].[HomePhone] AS [HomePhone], 
          [v_EmpData].[WorkCellPhone] AS [WorkCellPhone]
      FROM [dbo].[v_EmpData] AS [v_EmpData]) AS [Extent8] ON 1 = 1 ) AS [Join13] ON ([Extent1].[TakenUIN] = [Join13].[UIN]) OR (([Extent1].[TakenUIN] IS NULL) AND ([Join13].[UIN] IS NULL))
WHERE ([Extent1].[BeginTime] > (DATEADD (year, -1, SysDateTime()))) 
    AND ('C' <> [Extent1].[Status]) 
    AND ([Extent1].[BeginTime] >= '11/28/2012 12:00:00 AM') 
    AND ([Extent1].[BeginTime] < '11/29/2012 12:00:00 AM')

これは私の元のSQLクエリがどのように見えたか、そしてそれがより近くなることを望んでいたものです。

SELECT 
    ChartID,
    c.Status, 
    ...
    r.Website As Website, 

FROM tblChartersNew c 
    LEFT JOIN (SELECT [Dpt],[DptID] FROM [DRVRDiscipline].[dbo].[tblCharterCustomers] Where Valid=1 and DptID <> 'NONAFF' UNION SELECT Dpt, CONVERT(nvarchar,CustID) AS DptID FROM [DRVRDiscipline].[dbo].[tblCharterCustomers] Where Valid=1 and DptID = 'NONAFF') f 
    ON RTRIM(c.Dpt) = f.DptID LEFT JOIN [tskronos].WfcSuite.dbo.VP_ALLPERSONV42 p ON p.PersonNUM = c.TakenUIN 
    LEFT JOIN tblChartVehicles v ON v.ChartVehID = c.Veh 
    LEFT JOIN tblNACharter n ON CAST(n.NAID AS varchar) = RIGHT(c.Dpt, LEN(c.Dpt)-1) 
    LEFT JOIN tblChartReq r 
    ON r.ChartReqID = c.ChartReqID 
WHERE CONVERT(datetime,CONVERT(char(10),c.BeginTime,101)) = (SELECT TOP 1 CONVERT(datetime,CONVERT(char(10),BeginTime,101)) from tblChartersNew WHERE CONVERT(datetime,CONVERT(char(10),BeginTime,101)) >= CONVERT(datetime,CONVERT(char(10),GETDATE(),101)) ORDER BY BeginTime) 
    AND NOT c.ChartReqID IS NULL 
ORDER BY BeginTime, ISNULL(f.Dpt,c.Dpt)

また、ビューに[新規選択]を追加して、必要な列が3つだけの場合にすべての列が選択されないようにしましたが、違いは見られませんでした。LEFT JOIN v_EmpDataを追加する代わりに、LEFT OUTER JOINを追加してから、ビュー内のすべての列を選択します。SelectNewを無視しているようです。

クエリの大部分でLinqtoEntitiesを使用するように移行したいと思います。これは、インテリセンスを使用すると、クエリごとに個別の関数を用意しなくても、クエリのバリエーションを簡単に作成できるためです。プレーンな古いSQLを使用します。私は大きな混乱を起こすのに十分知っています。助言がありますか?

4

1 に答える 1

0

必要なもののような複雑なクエリの場合。

FunctionImport を調べることをお勧めします。

MSDN 関数のインポート

これにより、予想される生成された SQL に対して 1:1 になる LINQ を作成するという頭痛の種が解消されます。

于 2012-11-29T02:56:16.080 に答える