2012-01-17 82 views
3

我已经遇到了与我的Linq-to-sql有关的问题。将嵌套连接的高级SQL查询转换为Linq-to-sql

我有一个SQL查询,运行我想要的方式,通常我使用Linqer转换为Linq来查看一般想法。但是这次我的SQL查询似乎为Linqer提前了。 :/

我认为问题是嵌套在左外联接中的内联接。不幸的是,我从来没有遇到过这种情况,也不知道如何使用Linq来解决这个问题。

我的SQL查询看起来是这样的:

SELECT c.[Company], c.[Name_First], c.[Name_Last], ort.[IDOriginatorRoleType], 
     ort.[RoleType] AS [OriginatorRoleType], o.[IDOriginator], o.[IDWork], 
     o.[IDContact], m.[IDMedia], m.[IDWork], m.[FileName], m.[FileNameOnDisk], 
     m.[DateAdded], w.[IDWork] AS [IDWork2], w.[ArticleNumber], w.[Title], 
     w.[FrontPageLow], w.[FrontPageLowOnDisk], w.[FrontPageHigh], 
     w.[FrontPageHighOnDisk] 
FROM [dbo].[tblSubscriptionsWorks] AS sw 
INNER JOIN [dbo].[tblWorks] AS w ON sw.[IDWork] = w.[IDWork] 
LEFT OUTER JOIN [dbo].[tblMedias] AS m ON m.[IDWork] = w.[IDWork] 
LEFT OUTER JOIN ([dbo].[tblOriginators] AS o 
    INNER JOIN [dbo].[tblOriginatorRoles] AS ors ON 
      o.[IDOriginatorRole] = ors.[IDOriginatorRole] 
    INNER JOIN [dbo].[tblOriginatorRoleTypes] AS ort ON 
      ors.[IDOriginatorRoleType] = ort.[IDOriginatorRoleType] 
    INNER JOIN [dbo].[tblContacts] AS c ON 
      o.[IDContact] = c.[IDContact]) ON 
(o.[IDWork] = w.[IDWork]) AND (ort.[IDOriginatorRoleType] = 1) 
WHERE sw.[IDWork_Subscription] = 9942 
+0

我会认为这些连接是'链接'而不是'嵌套'。 – onedaywhen 2012-01-17 10:24:50

+0

你有没有看过使用LinqPad,它可能是非常有用的 – Kane 2012-01-17 10:26:18

回答

2

左外连接是不是有什么我可以看到一个问题。您只需将语句

LEFT OUTER JOIN ([dbo].[tblOriginators] AS o 
    INNER JOIN [dbo].[tblOriginatorRoles] AS ors ON 
      o.[IDOriginatorRole] = ors.[IDOriginatorRole] 
    INNER JOIN [dbo].[tblOriginatorRoleTypes] AS ort ON 
      ors.[IDOriginatorRoleType] = ort.[IDOriginatorRoleType] 
    INNER JOIN [dbo].[tblContacts] AS c ON 
      o.[IDContact] = c.[IDContact]) ON 
(o.[IDWork] = w.[IDWork]) AND (ort.[IDOriginatorRoleType] = 1) 

分成另一个IQueryable列表。在这个例子中,变量db是datacontext。这是一个解决方案的建议:

//selects all the columns that is just in the select from the left join 
var leftJoin= 
       (
        from o in db.tblOriginators 
        join ors in db.tblOriginatorRoles 
         on o.IDOriginatorRole equals ors.IDOriginatorRole 
        join ort in db.tblOriginatorRoleTypes 
         on ors.IDOriginatorRoleType equals ort.IDOriginatorRoleType 
        join c in db.tblContacts 
         on o.IDContact equals c.IDContact 
        where ort.IDOriginatorRoleType==1 
        select new 
        { 
         o.IDWork, 
         c.Company, 
         c.Name_First, 
         c.Name_Last, 
         ort.IDOriginatorRoleType, 
         ort.RoleType, 
         o.IDOriginator, 
         o.IDContact 
        } 
       ); 
var output=(
     from sw in db.tblSubscriptionsWorks 
     join w in db.tblWorks 
      on sw.IDWork equals w.IDWork 
     from m in db.tblMedias 
      .Where(x=>x.IDWork==w.IDWork).DefaultIfEmpty() 
     //Left join with the IQueryable list 
     from org in leftJoin 
      .Where(x =>x.IDWork==w.IDWork).DefaultIfEmpty() 
     where 
      sw.IDWork_Subscription == 9942 
     select new 
     { 
      org.Company, 
      org.Name_First, 
      org.Name_Last, 
      org.IDOriginatorRoleType, 
      OriginatorRoleType=org.RoleType, 
      org.IDOriginator, 
      org.IDWork, 
      m.IDMedia, 
      m.IDWork, 
      m.FileName, 
      m.FileNameOnDisk, 
      w.FrontPageLow, 
      w.FrontPageLowOnDisk, 
      w.FrontPageHigh, 
      w.FrontPageHighOnDisk 
     } 
    ); 
+0

对不起,我花了这极其漫长的时间来回到这个。该项目已经休息了很长时间,但现在又重新开始。 – 2013-02-07 23:11:00