Lambda语法。如何通过1到多个键连接

时间:2018-02-01 16:06:28

标签: c# sql entity-framework linq lambda

我尝试从本机sql重写查询到 inq lambda语法(不是 linq查询语法

LINQ (不能正常工作)

 var result = _uow.Repository<TableA>().Get().AsNoTracking()
    .GroupJoin(
        _uow.Repository<TableB>().Get().AsNoTracking(),
        a => new { a.TabNotesCodeId, a.TabLabelCodeId },
        b => b.ElementNameId
        (b, a) => new SubSection
        {
            SubSectionName = b.CustomValue ?? a.TabLabelCodeId,
            SubSectionNote = b.CustomValue ?? a.TabLabelCodeId,
        })
    .Where(a => a.ResourceId == 1);

SQL

SELECT [SubSectionName] = ISNULL(B.CUSTOMVALUE,A.TABLABELCODEID),
       [SubSectionNote] = ISNULL(B.CUSTOMVALUE,A.TABNOTESCODEID)
FROM TableA as A LEFT JOIN 
     (SELECT CUSTOMVALUE, ELEMENTNAMEID FROM TableB WHERE DISPLAYSETTINGID = 1) as B
        ON B.ELEMENTNAMEID IN ( A.TABNOTESCODEID, A.TABLABELCODEID)
WHERE A.RESOURCEID = 1

如何重写 sql ON B.ELEMENTNAMEID IN(A.TABNOTESCODEID,A.TABLABELCODEID) lambda syntax < /强>

...
  a => new { a.TabNotesCodeId, a.TabLabelCodeId },
  b => b.ElementNameId
....

(没有工作)

2 个答案:

答案 0 :(得分:0)

通常我会建议遵循我的SQL转换规则,但这很复杂,我觉得它不会有所帮助。

要在作为左连接的非等值连接上使用查询理解语法,使用lambda语法表达连接条件似乎最简单,所以我只是将子查询与连接条件结合起来:

var ans = from A in TableA
          where A.ResourceID == 1
          from B in TableB.Where(b => b.DisplaySettingID == 1).Where(b => b.ElementNameID == A.TabNotesCodeID || b.ElementNameID == A.TabLabelCodeID).DefaultIfEmpty()
          select new {
              SubSectionName = (B.CustomValue ?? A.TabLabelCodeID),
              SubSectionNote = (B.CustomValue ?? A.TabNotesCodeID)
          };

用于生成交叉连接的多个from子句的lambda等价物是SelectMany,因此转换为lambda语法:

var ans2 = TableA.Where(a => a.ResourceID == 1)
                 .SelectMany(a => TableB.Where(b => b.DisplaySettingID == 1).Where(b => b.ElementNameID == a.TabNotesCodeID || b.ElementNameID == a.TabLabelCodeID)
                                        .DefaultIfEmpty(),
                                        (a, b) => new {
                                            SubSectionName = (b.CustomValue ?? a.TabLabelCodeID),
                                            SubSectionNote = (b.CustomValue ?? a.TabNotesCodeID)
                                        }
                            );

答案 1 :(得分:0)

经过无数次实验,我找到了解决方案:

                    _uow.Repository<TableA>().Get().AsNoTracking()
                    .GroupJoin(
                        _uow.Repository<TableB>().Get().AsNoTracking().Where(b => b.DisplaySettingId == 1),
                        a => new { note = a.TabNotesCodeId, label = a.TabLabelCodeId },
                        b => new { note = b.ElementNameId, label = b.ElementNameId },
                        (a, b) => new { a,b })
                    .Where(joinTables => joinTables.a.ResourceId == 1)
                    .SelectMany(
                        joinTables => joinTables.b.DefaultIfEmpty(),
                        (joinTables, b) => new SubSection()
                        {
                            LayoutTab = joinTables.a.LayoutTab,
                            SubSectionName = b.CustomValue ?? joinTables.a.TabLabelCodeId,
                            SubSectionNote = b.CustomValue ?? joinTables.a.TabNotesCodeId
                        });