2011-10-14 125 views
13

有許多關於LINQ和多個連接的文章。 但是,我沒有找到任何解決方案,我想要做的連接。LINQ to Entity:多個連接條件

的SQL相當於將是這樣的:

SELECT * FROM table1 a 
LEFT JOIN table2 b ON a.col1 = b.key1 AND 
a.col2 = b.key2 AND 
b.from_date <= now() AND 
b.deleted = 0; 

下面是我嘗試

var query = (from x in context.table1 
      join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2} 
      into result 
      from result...... 

我如何可以添加日期的產生額外的條件,並刪除了大量的LINQ查詢之一旗? 如果我使用.Where條件,那麼這被視爲內連接,而不是左連接。

回答

32

另一種方式也能像

var query = (from x in context.table1 
      join y in context.table2 on 
      new { 
        Key1 = x.col1, 
        Key2 = x.col2 
        Key3 = true, 
        Key4 = true 
       } 
      equals 
      new { 
        Key1 = y.key1, 
        Key2 = y.key2, 
        Key3 = y.from_date< DateTime.Now, 
        Key4 = !y.deleted 
       } 
      into result 
from r in result.DefaultIfEmpty() 
select new {x.Something, r.Something} 
1

你不只是用第二個查詢過濾第一個結果集嗎?

var query = (from x in context.table1 
      join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2} 
      into result 
query = from x in query 
     where ... 

會這樣嗎?

11

LINQ支持聯接語法和舊的ANSI-82 WHERE語法。使用後面的,你可以做你想要的東西

var nowTime = DateTime.Now; 
var query = from a in context.table1 
      from b in context.table2 
      where a.col1 == b.key1 
       && a.col2 == b.key2 
       && b.from_date < nowTime 
       && b.deleted == false 
      select ???; 

或者,你可以使用where和join的混合。 (要知道,在LINQ查詢的順序並不需要模仿你在SQL做什麼以及訂單更靈活。)

var nowTime = DateTime.Now; 
var query = from b in context.table2 
      where b.from_date < nowTime 
       && b.deleted == false 
      join a on new {b.key1, b.key2} equals new {a.col1, a.col2} 
      select ???; 
0

我有問題,在匿名的對象屬性的命名:

var subscriptions = context.EmailSubscription.Join(context.EmailQueue, 
        es => new { es.Id, 9 }, 
        eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId }, 
        (es, eq) => new { es.Id, eq.Id } 
       ).ToList(); 

編譯器不高興所以上面的答案幫助我弄清楚什麼是錯的,這裏是我的工作解決方案。我花了一段時間才找到愚蠢的錯誤:):

var subscriptions = context.EmailSubscription.Join(context.EmailQueue, 
        es => new { EmailSubscriptionId = es.Id, EmailTemplateId = 9 }, 
        eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId }, 
        (es, eq) => new { es.Id, eq.Id } 
       ).ToList();