2010-10-20 32 views
3

我有一個允許用戶執行大量搜索的表單。根據輸入的搜索條件,需要連接的表格會有所不同。 (我下面的例子是非常簡單的,因爲兩個表使用相同的子表加入,但實際問題並不那麼簡單。)C#LINQ:如何正確堆疊LINQ查詢

我一直在使用我稱之爲LINQ堆棧的技術,如下所示:

IQueryable<LogENT> results = Context.AssignedLogsENT.Where(l => l.AgencyId); 

if(txtFirstName.Text != null) 
    results = from r in results 
     join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId 
     join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId 
     && !a.Deleted && 
     p.FirstName.StartsWith(Object.FirstName) 
     select r; 

if(txtLastName.Text != null) 
    results = from r in results 
     join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId 
     join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId 
     && !a.Deleted && 
     p.LastName.StartsWith(Object.LastName) 
     select r; 

所以你看看是否設置了某個文本字段,我會根據需要添加到查詢中。這實際上工作正常,除了當我使用SQL Profiler查看生成的查詢時,每次添加新條件時都是INNER JOINing表。

即LogAssignments表包含3,4,5次。有沒有辦法阻止它多次加入同一個表?

或者,有沒有更好的辦法可以做到這一點?我已經看過Predicate Builder,但它似乎不允許加入表格,這在我的情況中是一個要求。

謝謝!

回答

1

如果你只使用一個查詢,你可以修改它是這樣的:

results = from r in results 
     join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId 
     join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId 
     && !a.Deleted && 
     (txtFirstName.Text != null || p.FirstName.StartsWith(Object.FirstName)) && 
     (txtLastName.Text != null || p.LastName.StartsWith(Object.LastName)) 
     select r; 
+0

謝謝,但我需要一種方法來使「連接」可選以及... – msigman 2010-10-22 14:34:12

+0

@ user482286:你檢查了生成的查詢,看看實際上有加入因此? – 2010-10-22 15:57:32

0

您可以構建基礎結果,然後動態添加where子句。

+0

但問題是哪來取決於連接表,所以我不能引用連接表在動態添加wheres ... – msigman 2010-10-22 14:34:44

2
IQueryable<LogENT> results = Context.AssignedLogsENT.Where(l => l.AgencyId); 


results = from r in results 
    join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId 
    join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId 
    && !a.Deleted 
    select r; 

if(txtFirstName.Text != null) 
    results = from r in results 
     p.FirstName.StartsWith(Object.LastName) 
     select r; 

if(txtLastName.Text != null) 
    results = from r in results 
     p.LastName.StartsWith(Object.LastName) 
     select r; 
+0

此方法不起作用,因爲「p」未在任何後續查詢中定義。 – msigman 2010-10-20 23:45:07