我有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选择
这是真的吗?还是最简单的方法?
答案 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))