Linq到sql左外连接

时间:2011-07-28 01:19:53

标签: linq-to-sql

我在SQL中有以下内容:

SELECT * FROM (SELECT Teikoku_Sections.Section_ID, Teikoku_Sections.Section_Name, Teikoku_Sections.Section_Code, Teikoku_Sections.Show_In_Menu FROM Teikoku_Sections WHERE Teikoku_Sections.Show_In_Menu = 1) AS Sections
LEFT OUTER JOIN (SELECT Teikoku_Divisions.Division_ID, Teikoku_Divisions.Division_Name, Teikoku_Divisions.Division_Code, Teikoku_Divisions.Section_ID, Teikoku_Divisions.Show_In_Menu FROM Teikoku_Divisions WHERE Teikoku_Divisions.Show_In_Menu = 1) AS Divisions
ON Sections.Section_ID = Divisions.Section_ID;

在两个表Teikoku_Sections和Teikoku_Divisions上执行左外连接,并将两个表中的可见项连接在一起。

表格的结构如下:

Teikoku_Section: Section_ID int, Section_Name nvarchar(50), Section_Code int, Show_In_Menu位

Teikoku_Divisions: Division_ID int, Division_Name nvarchar(50) Division_Code int, Section_ID int,< ==父节的ID Show_In_Menu位

我想最后得到一个表格,显示Show_In_Menu为true的所有部分和分区,但在某些情况下,可能没有任何与部分对应的分区,因此LEFT OUTER JOIN。

我无法理解如何在linq to sql中执行此操作。

到目前为止,我有:

//Get All Visible sections
    IQueryable<Teikoku_Section> visibleSections = from section in db.Teikoku_Sections where section.Show_In_Menu select section;
    //Get all visible divisions
    IQueryable<Teikoku_Division> visibleDivisions = from division in db.Teikoku_Divisions where division.Show_In_Menu select division;
    //Join the two together
    IQueryable menuItems = visibleSections.GroupJoin(visibleDivisions, section => section.Section_ID,
        division => division.Section_ID, (section, divisions) => new
        {
            Section_ID = section.Section_ID,
            Section_Name = section.Section_Name,
            Division_ID = divisions.Select(d => d.Division_ID),
            Division_Name = divisions.Select(d => d.Division_Name),
        });

    return menuItems;

哪个不太合适......我想我可能会错过一个SelectMany(),但我无法确定在哪里或如何放置它。

2 个答案:

答案 0 :(得分:0)

查看DefaultIfEmpty(http://msdn.microsoft.com/en-us/library/bb355419.aspx)

答案 1 :(得分:0)

按照Jim Wooley的建议,使用linq语法完成此操作。我使用以下语法进行查询:

IQueryable<Teikoku_Section> visibleSections = from section in db.Teikoku_Sections
                                                  where section.Show_In_Menu
                                                  select section;

    IQueryable<Teikoku_Division> visibleDivisions = from division in db.Teikoku_Divisions
                                                    where division.Show_In_Menu
                                                    select division;

    IQueryable menuItems = from section in visibleSections
                join division in visibleDivisions on section.Section_ID equals division.Section_ID into joined_SectionDivision
                from menuItem in joined_SectionDivision.DefaultIfEmpty()
                select new
                {
                    Section_ID = section.Section_ID,
                    Section_Name = section.Section_Name,
                    Division_ID = (menuItem == null) ? null : (int?)menuItem.Division_ID,
                    Division_Name = menuItem.Division_Name ?? null
                };

我花了好几个小时才最终得到这个结果,所以这里有几个解释,可能是处于相同情况的任何人。

我不想要一个简单的左外连接,但是在两个表的项目上都有条件的连接,即Show_In_Menu对于两个表中的项都是true,但不一定是同时的,所以一个部分可以看到,但它是分歧可能不会,在这种情况下,我只希望结果中没有任何分割的部分在结果中出现一次。

出于这个原因,我创建了两个临时表,只有可见部分和除法项,然后使用这两组结果执行左外连接。

令我困惑的一件事是.DefaultIfEmpty()部分,它是处理null连接项所必需的。希望这有助于某天试图做左外连接的人。