2013-04-12 128 views
0

我有一堆參數傳入使用LINQ to SQL的C#方法。所有這些參數都是來自UI的過濾器。我需要篩選的四個參數位於同一個表的同一列中。例如,該表可能看起來像:LINQ to SQL多次查詢同一列

ID | FK_ID | Name | Value 

1 1 Param1 p1Val 
2 1 Param2 p2Val 
3 1 Param3 p3.Val 
3 1 Param4 p4.Val 

我需要的濾波器參數和匹配到值列,並確保該名稱是正確的。目前,我通過多次加入同一張表來做到這一點......但我擔心這太低效了。什麼是最好的方法來做到這一點?我想我想動態構建查詢,這樣我就可以檢查設置了哪些過濾器,但是我正在努力應該如何構建我的結果集。 現在,它看起來像:(FYI ContextProperties是有問題的表)

var result = 

from f in dataContext.Faults 
join m in dataContext.Messages on f.FaultID equals m.FaultID    
join c in dataContext.ContextProperties on m.MessageID equals c.MessageID 
join cp in dataContext.ContextProperties on c.MessageID equals cp.MessageID 
join cpp in dataContext.ContextProperties on cp.MessageID equals cpp.MessageID 
join cppp in dataContext.ContextProperties on cpp.MessageID equals cppp.MessageID 
where (f.DateTime >= initDate && f.DateTime <= finishDate) && 
        f.FaultID == (faultID != Guid.Empty ? faultID : f.FaultID) && 
        f.Application == (!string.IsNullOrEmpty(application) ? application : f.Application) && 
        f.FaultCode == (!string.IsNullOrEmpty(faultCode) ? faultCode : f.FaultCode) && 
        f.FailureCategory == (!string.IsNullOrEmpty(failureCategory) ? failureCategory : f.FailureCategory) && 
        f.ErrorType == (!string.IsNullOrEmpty(errorType) ? errorType : f.ErrorType) && 
        (f.FaultSeverity >= 0 && f.FaultSeverity <= maxFaultSeverity) 
        where (c.Value.ToString() == (!string.IsNullOrEmpty(geniusReference) ? geniusReference : c.Value.ToString()) 
         && c.Name.ToString() == "GeniusReference") 
        where (cp.Value.ToString() == (!string.IsNullOrEmpty(programNumber) ? programNumber : cp.Value.ToString()) 
         && cp.Name.ToString() == "ProgramGeniusNumber") 
        where (cpp.Value.ToString() == (!string.IsNullOrEmpty(platform) ? platform : cpp.Value.ToString()) 
         && cpp.Name.ToString() == "Platform") 
        where (cppp.Value.ToString() == (!string.IsNullOrEmpty(modifiedBy) ? modifiedBy : cppp.Value.ToString()) 
         && cppp.Name.ToString() == "ModifiedBy") 
        select new FaultsWithFilters { 
                DateTime = f.DateTime 
                ,FaultID = f.FaultID 
                ,Scope = f.Scope 
                ,FaultCode = f.FaultCode 
                ,FaultSeverity = f.FaultSeverity 
                ,ErrorType = f.ErrorType 
                ,Description = f.Description 
                ,FaultDescription = f.FaultDescription 
                ,FailureCategory = f.FailureCategory 
                ,GeniusReference = c.Value.ToString() 
                ,ProgramNumber = cp.Value.ToString() 
                ,Platform = cpp.Value.ToString() 
                ,ModifiedBy = cppp.Value.ToString() 
                }; 

接着一堆,語句和選擇的。先謝謝您的幫助! PS抱歉糟糕的格式。

+0

你想要的結果怎麼看喜歡?我很難根據現有問題對其進行可視化。 –

+0

嘿馬修,我已經更新了原始帖子的完整查詢,因爲它現在。 FaultsWithFilters是我製作的自定義課程。更新是否足以讓您獲得結果集的可視化? –

+0

因此,您試圖獲取給定MessageID的所有ContextProperties,其中ContextProperties的名稱與「GeniusReference」,「ProgramGeniusNumber」,「Platform」,「ModifiedBy」中的任何一個匹配。聲音正確嗎? –

回答

0

在當時創建您的查詢一個子句,而不是真的壞看field == (filterSet ? filter : field)

首先加入所有必要的表:

var query = dataContext.Faults.Join(dataContext.Messages, f => f.FaultID, m => mFaultID, new { f, m }) 
           .Join(dataContext.ContextProperties, x => x.m.MessageID, c => c.MessageID, new { x.f, x.m, c }); 
           // add all other joins here 
           // and all where conditions that are always valid 

然後添加條件where條件:

if(!string.IsNullOrEmpty(geniusReference)) 
{ 
    query = query.Where(x => x.c.Value.ToString() == geniusReference); 
} 

// instead of: 
// where (c.Value.ToString() == (!string.IsNullOrEmpty(geniusReference) ? geniusReference : c.Value.ToString()) 

在末尾添加投影:

var results = from x in query 
       select new FaultsWithFilters { 
        DateTime = x.f.DateTime 
        ,FaultID = x.f.FaultID 
        ,Scope = x.f.Scope 
        ,FaultCode = x.f.FaultCode 
        ,FaultSeverity = x.f.FaultSeverity 
        ,ErrorType = x.f.ErrorType 
        ,Description = x.f.Description 
        ,FaultDescription = x.f.FaultDescription 
        ,FailureCategory = x.f.FailureCategory 
        ,GeniusReference = x.c.Value.ToString() 
        ,ProgramNumber = x.cp.Value.ToString() 
        ,Platform = x.cpp.Value.ToString() 
        ,ModifiedBy = x.cppp.Value.ToString() 
       }; 
+0

這看起來不錯!而且更清潔!恐怕這麼多連接會導致性能問題。 ContextProperties表只會隨着時間的推移而不斷增長。做所有這些連接仍然是最好的選擇? –

+0

我要求做所有這些連接的原因是,對於「GeniusReference」,「ProgramGeniusNumber」,「Platform」,「ModifiedBy」參數中的每一個參數,只有在設置了它們的情況下,我纔想加入到ContextProperties表中,否則我會有不必要的連接。 –