Linq Lambda多桌(4桌)LEFT JOIN

时间:2014-11-16 10:18:41

标签: linq entity-framework lambda

我有4张桌子;

TMain >> MainId (PK)

T1 >> T1_Id, MainId, X (PK and FK) X is decimal

T2 >> T2_Id, MainId, X (PK and FK) X is decimal

T3 >> T3_Id, MainId, X (PK and FK) X is decimal

这里是SQL输出;

SELECT TMain.*, (ISNULL(T1.X,0) + ISNULL(T2.X,0) + ISNULL(T3.X,0)) AS TOTAL FROM TMain

LEFT OUTER JOIN T1 ON TMain.MainId = T1.MainId

LEFT OUTER JOIN T2 ON TMain.MainId = T2.MainId

LEFT OUTER JOIN T3 ON TMain.MainId = T3.MainId

如何编写 LINQ LAMDA

   var AbbA = MyContext.TMain
                    .GroupJoin(
                        MyContext.T1,
                        q1 => q1.TMainId,
                        q2 => q2.TMainId,
                        (x, y) => new { A = x, T1_A = y })
                            .SelectMany(
                            xy => xy.T1_A.DefaultIfEmpty(),
                            (x, y) => new { A = x.A, T1_A = y })
                    .GroupJoin(
                        MyContext.T2,
                        q1 => q1.A.TMainId,
                        q2 => q2.TMainId,
                        (x, y) => new { A = x, T2_A = y })
                            .SelectMany(
                            xy => xy.T2_A.DefaultIfEmpty(),
                            (x, y) => new { A = x.A, T2_A = y })
                    .GroupJoin(
                        MyContext.T3,
                        q1 => q1.A.A.TMainId,
                        q2 => q2.TMainId,
                        (x, y) => new { A = x, T3_A = y })
                            .SelectMany(
                            xy => xy.T3_A.DefaultIfEmpty(),
                            (x, y) => new { A = x.A, T3_A = y })
                    .Select(q => new 
                    {
                        TMainId = q.A.A.A.TMainId,
                        Total = (q.T3_A.X == null ? 0 : q.T3_A.X) +
                                (q.A.T2_A.X == null ? 0 : q.A.T2_A.X) +
                                (q.A.A.T1_A.X == null ? 0 : q.A.A.T1_A.X),
                    }).ToList();

所以我想访问T1字段或TMain字段

我写了q.A.A.T1_A.X或q.A.A.A.在linq选择

这是真的吗?还是最简单的方法?

1 个答案:

答案 0 :(得分:0)

我现在无法测试是否有效,但有时您可以编写GroupJoin(如果您希望T1中有0或N个寄存器):

.GroupJoin(MyContext.T1,
     q1 => q1.TMainId,
     q2 => q2.TMainId,
     (x, y) => new { A = x, T1_A = y.DefaultIfEmpty() })

或(如果您希望T1中有0或1个寄存器)

.GroupJoin(MyContext.T1,
     q1 => q1.TMainId,
     q2 => q2.TMainId,
     (x, y) => new { A = x, T1_A = y.FirstOrDefault() })

它总是取决于你想要为下一个lambda返回什么,在这种情况下你不需要SelectMany()。但是如果你不能相应地映射表之间的关系,那么这段代码将是linq / lambda最简单的左连接。

如果将表TMain和T1之间的关系映射到“HasOptional”,则可以简化,如:

modelBuilder.Entity<T1>()
            .HasOptional(x => x.TMain)
            .WithMany(y => y.T1s)
            .HasForeignKey(x => x.TMaidId);

“HasOptional()”向Entity Framework显示此关系是可选的,因此LEFT JOIN将用于挂载查询。如果使用“HasRequired()”,将使用JOIN。

因此,您可以使用Include():

var AbbA = MyContext.TMain
     .Include(x => x.T1s)

左连接T1和T2:

var AbbA = MyContext.TMain
     .Include(x => x.T1s.Select(y => y.T2s))