2013-12-11 102 views
0

我已经形成了以下LINQ查询,但.. .. 。 。如何编写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 }; 
+0

你考虑基于条件建设2个不同的查询,反对试图动态组装它 – Konstantin

+0

我建议建立在数据库级和查询相应的视图它通过LINQ。 –

+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不会改变结果的类型; query对于某些TIQueryable<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.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是被设置为-1如果condition1整数如果condition1为假,则YetAnotherField是设置为null的字符串。

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

如果两个源是相同类型的,它就会工作 –

+0

这是真的(他似乎也使用TypedDataSet,当然它也是不同的类型) 。你的回答是正确的。另一个建议:有时候你应该在数据库级别(在DataAdapter中)使用UNION连接表。 – dovid