【问题标题】:How Write LINQ join mutiple conditions如何编写 LINQ 连接多个条件
【发布时间】:2013-12-29 20:21:17
【问题描述】:

我已经形成了以下 LINQ 查询,但是...... . .

如果你有第三个连接......在这种情况下是条件......如何写这个?

示例:

 var query = from trip in db.Trips
from driver in db.Drivers
condition1 ?  join X in other_table : join Y in other_table2 
where trip.DriverId == driver.DriverId ||
      trip.CoDriverId == driver.DriverId
select new { driver.DriverId, trip.TripId };

【问题讨论】:

  • 您是否考虑过根据条件构建 2 个不同的查询,而不是尝试动态组装它
  • 我建议在数据库级别创建一个适当的视图并通过 LINQ 进行查询。
  • 您可以对所有其他表进行左连接,然后对它们进行操作

标签: c# sql linq join conditional


【解决方案1】:

如果我理解了核心问题,那么:

 var query = from trip in db.Trips
             from driver in (condition1 ? cdb.Drivers1 : cdb.Drivers2)
             where trip.DriverId == driver.DriverId ||
             trip.CoDriverId == driver.DriverId
             select new { driver.DriverId, trip.TripId };

【讨论】:

  • 如果两个来源是同一类型,它会工作,否则不会
  • 确实如此(他似乎也使用了TypedDataSet,那么肯定是不同的类型)。你的答案是正确的。另一个建议:有时您应该在数据库级别(在 DataAdapter 中)使用 UNION 连接表。
【解决方案2】:

如果other_tableother_table2 的类型相同,那么最简单的方法是:

IQueryable<SomeType> joinTable = condition1 ? other_table : other_table2;

然后使用join j in joinTable 作为查询的一部分。

否则,如果您只是使用连接来限制 where 条件,而不是影响字段,您可以先写 query 忽略它,然后添加类似:

if(condition1)
   query = query.Where(q => other_table.Where(o => foo==bar).Select(o => o.DriverId).Contains(q.DriverId));
else
   query = query.Where(q => other_table.Select(o => o.DriverId).Contains(q.DriverId));

这里foo==bar 的限制是为了表明我们可以在必要时为这些进一步的Where 子句添加相当多的细节。主要的是Where 不会改变结果的类型;对于某些TqueryIQueryable&lt;T&gt;,并且在Where 之后仍然如此,因此我们可以将该查询分配回query

如果连接是添加值,那么:

var newQuery = condition1
  ? query.Join(other_table, q=>DriverId, ot => ot.DriverId, (q, ot) => new {q.DriverID, q.TripId, ot.OtherField}
  : query.Join(other_table2, q=>DriverId, ot => ot.DriverId, (q, ot) => new {q.DriverId, q.TripId, OtherField = ot.YetAnotherField};

请注意,other_table.OtherFieldot.YetAnotherField 必须属于同一类型。这取决于编译器创建的任何匿名类与同一类具有相同的名称、顺序和字段类型,因此可以推断出newQuery 的类型(并且对于每个分支都是相同的)。如果它们不是同一类型,那么您需要将一个转换为另一个的类型,或者执行以下操作:

var newQuery = condition1
  ? query.Join(other_table, q=>DriverId, ot => ot.DriverId, (q, ot) => new {q.DriverID, q.TripId, ot.OtherField, YetAnotherField = (string)null}
  : query.Join(other_table2, q=>DriverId, ot => ot.DriverId, (q, ot) => new {q.DriverId, q.TripId, OtherField = -1, ot.YetAnotherField};

在最后一个示例中,OtherField 是一个整数,如果condition1 为真,则设置为-1,而YetAnotherField 是一个字符串,如果condition1 为假,则设置为null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-29
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多