如何编写LINQ加入多个条件

时间:2013-12-11 17:45:27

标签: c# sql linq join conditional

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

如果你有第三次加入...在这种情况下是condional ...怎么写这个?

示例:

 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 个答案:

答案 0 :(得分: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不会改变结果的类型;对于某些queryIQueryable<T>T,并且在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.OtherField

请注意,ot.YetAnotherFieldnewQuery必须属于同一类型。这取决于编译器创建具有相同名称,字段顺序和类型的任何匿名类作为同一个类,因此可以推导出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

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

答案 1 :(得分:0)

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

 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 };