将带有嵌套连接的高级SQL查询转换为Linq-to-sql

时间:2012-01-17 10:15:08

标签: sql linq sql-server-2008 linq-to-sql .net-4.0

我遇到了我的Linq-to-Sql。

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

我认为问题是嵌套在LEFT OUTER JOIN中的INNER JOINS。不幸的是,我以前从未遇到过这个问题,也不知道如何使用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

1 个答案:

答案 0 :(得分: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
        }
    );