View Linq to实体查询添加内部联接而不是左联接

View Linq to实体查询添加内部联接而不是左联接,view,linq-to-entities,left-join,inner-join,View,Linq To Entities,Left Join,Inner Join,我想知道为什么生成内部联接而不是左联接,为什么在联接之前选择整个视图而不是只添加左联接视图 我正试图发布一个信息表,它分布在几个表上。基本上,我想按日期搜索并返回今天、昨天、本月发生的事件的所有信息——无论用户选择什么。查询很长。我将DefaultIfEmpty添加到除主表之外的所有表中,试图获得左连接,但这只会造成混乱 using (TransitEntities t = new TransitEntities()) { var charters = from c in t.tbl

我想知道为什么生成内部联接而不是左联接,为什么在联接之前选择整个视图而不是只添加左联接视图

我正试图发布一个信息表,它分布在几个表上。基本上,我想按日期搜索并返回今天、昨天、本月发生的事件的所有信息——无论用户选择什么。查询很长。我将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)
我还在视图上添加了一个selectnew,以避免在我只需要三个列时选择所有列,但这似乎没有什么区别。它不添加左联接v_EmpData,而是添加左外部联接,然后选择视图中的所有列。它似乎忽略了Select New


我真的很想在大多数查询中使用Linq to Entities,因为intellisense可以更轻松地确保它是正确的,并且有各种查询,而不必为每个查询使用单独的函数,但可能我需要坚持使用普通的SQL。我知道的足以把事情搞得一团糟。有什么建议吗?

对于复杂的查询,如您需要的内容

我建议你调查一下


这将为您省去创建与预期生成的SQL成1:1的LINQ的麻烦。

在许多令人沮丧的日子之后,我注意到我没有使用到。在许多令人沮丧的日子之后,我注意到我没有使用到。产生的SQL仍然是垃圾,所以我可能不会使用它,但它可以工作。我仍然不明白为什么它只是在内部连接中添加一个左连接,而不是一个直接的左连接,但是我想这对于linq来说太复杂了。从t.TBLCharter中的c加入t.TBLCharter中的v在c.Veh上的车辆等于v.ChartVehID从列表1.DefaultIfEmpty中的v1进入列表1。。。选择新建{Veh=v1.Descr,…}