在LINQ Lambda中的on子句中具有两个等于的内部联接

时间:2019-01-03 09:20:40

标签: linq lambda

我正在尝试将Sql查询转换为Linq Lambda样式查询。认为这很容易,但事实并非如此。

SQL查询如下;

select distinct t1.ID from table1 t1
    inner Join table2 t2on (t2.FromId= t1.Id or t2.ToId= t1.Id)
where t1.TenantId = 12
and t2.wId= 51

到目前为止,我遇到的所有示例都是针对一个子句联接的。我写了这样的东西

    actStaList = _db.t1
        .Join(_db.t2,
        s => s.ID,
        wf => wf.ToId,
        (s, wf) => new { t1= s, t2= wf }
        )
        .Where(a => a.t1.Tenant.Guid == _tenantGuid)
        .Select (m=>m.t1.ID)
        .ToList();

很明显,这不能作为上面的sql查询使用,但这仍然是一个开始。 仍然我不知道该在INNER JOINDistinct关键字中添加第二部分。

2 个答案:

答案 0 :(得分:2)

您拥有的一个选择是使用两个单独的Linq查询并合并结果(并消除重复项)。

 var left = t1.Join(t2,
                    s => s.ID,
                    wf => wf.ToId,
                    (s, wf) => new { t1= s, t2= wf }
                    ).Select(x=>x);

var right = t1.Join(t2,
                    s => s.ID,
                    wf => wf.FromId,
                    (s, wf) => new { t1= s, t2= wf }
                    ).Select(x=>x);

    var actStaList = left.Concat(right).Select(m=>m.t1.ID)
                                       .Distinct();

请注意,我在OP中的示例中省略了Where子句,Sql版本和您尝试的Linq版本似乎都具有不同的条件。您可以自己添加它们。

答案 1 :(得分:1)

LINQ Join语句仅支持equi-joins。对于其他类型的相等性,您不能使用Join语句,而必须手动编码相等性。这在查询语法中要容易得多:

actStaList = (
    from t1 in _db.table1
    from t2 in _db.table2
    where t2.FromId == t1.Id || t2.ToId == t1.Id
    where t1.TenantId == 12 && t2.wId == 51
    select t1.ID
    ).Distinct();

为便于记录,您可以通过将它作为SQL Distinct语句执行来避免使用EXISTS语句:

actStaList =
    from t1 in _db.table1
    where t1.TenantId == 12 
    where (from t2 in _db.table2
           where t2.wId == 51 && (t2.FromId == t1.Id || t2.ToId == t1.Id)
           select t2).Any()
    select t1.ID;