簡體   English   中英

將多個變量where子句應用於linq查詢

[英]Applying multiple variable where clauses to linq query

我正在使用到sql查詢的行創建實用程序,該實用程序將在datagrid中加載數據。

由於數據集超過80,000條記錄,因此linq查詢將處理篩選,以使篩選保持在UI線程之外。 我無法直接在WPF中使用過濾器來過濾數據網格,因為UI線程將立即處理該過濾器,從而將窗口鎖定了3分鍾(過濾器將要應用)。

過濾選項由許多開關(功能為復選框)控制,如果選中,則返回bool。

我想使用這些開關來影響行查詢,例如,如果選中了完成項目選項,則對行查詢的等效更改將是將completed equals true添加為where子句,但是,如果未選中它們,我只是希望忽略該選項。

為了澄清,如果未選中顯示已完成項目的復選框,我想顯示所有項目,無論已完成還是未完成。 如果選中了顯示已完成項目的復選框,那么我想顯示已完成等於true的所有項目。

當前,我正在將子句以query = query.Where(r => r.completed == true)的形式添加到名為query的查詢對象中,但是這些query = query.Where(r => r.completed == true)需要包裝在if語句中-我不能簡單地采用開關,因為如果開關為假,我想忽略過濾,而不是專門添加檢查某個屬性設置為false的條件。

linq的一部分是否提供任何以這種方式實現可變行查詢的內容,或者if阻止了它的實現?

盡管已將其標記為可能的重復項,但我不確定這是因為另一個問題的解決方案是使用if語句,這是我要避免的內容。 八年前,這個問題也被問到了。自那時以來,.NET平台發生了很大變化。 我知道我可以使用多個if語句來處理此問題,但是如果有一個更有效和/或更易於閱讀的替代方法,我想使用它。

由於要求輸入代碼,

                IsBusy = true;
                String sqlConnect = connectionString;
                DbConnection connection = EFConnectionFactory.MakeConnection(sqlConnect);

                using (var db = new DbContext(connection)) {

                    var query = from l in db.Batch
                                join d in db.Document on l.id equals d.batch_id
                                group d by new { batchId = l.id, l.batchName, Added = l.added, Status = l.status, PaginationLocked = l.OKDate } into g
                                select new {
                                    BatchId = g.Key.batchId, BatchName = g.Key.batchName, CreatedDate = g.Min(t => t.added), g.Key.PaginationLocked, FinalisedDate = g.Max(t => t.OKDate), g
                                } into res
                                select new BatchChronologyDataModel {
                                    BatchId = res.BatchId,
                                    BatchName = res.BatchName,
                                    TotalDocuments = res.g.Count(),
                                    TotalOKayed = res.g.Where(s => s.documentOKayed != null).Count(),
                                    TotalExported = res.g.Where(s => s.editLocked != null).Count(),
                                    CreatedDate = res.g.Min(t => t.added),
                                    Status = res.g.Key.Status,
                                    PaginationLocked = res.PaginationLocked != null,
                                    FinalisedDate = res.g.Max(t => t.OKDate),
                                    DurationDays = DbFunctions.DiffDays(res.CreatedDate, res.FinalisedDate),
                                    BatchAgeDays = DbFunctions.DiffDays(res.CreatedDate, DateTime.Now),
                                    IsCompleted = res.g.Max(t => t.OKDate) != null,
                                };



                if (this.ShowLongCycleBatches) {
                    query = query.Where(r => r.DurationDays > 3);
                }

                if (this.Completed) {
                    query = query.Where(r => IsCompleted == true);
                }

這里的問題很簡單,我有多個子句必須按一定順序應用,即所有批處理已完成的項目在運行時都將刪除所有未完成的項目。

我希望顯示整個數據集,並且僅當選擇了一個選項時,才過濾掉不符合條件的所有內容。 我不想假設不選中一個框就等於一個假值。

由於有很多可選選項,因此我想知道是否有一種避免多條if語句的方法-我並不是說我對此有疑問,但是我在解決之前就已經研究過解決方案當找到更好的答案時,我沒有發現有用的東西並實施了巨大的解決方案。

在這種情況下,對我有用的解決方案是使用動態表達式API以字符串形式構成查詢(類似於SQL查詢),然后以查詢形式直接在查詢上運行query.Where("Status=hidden and BatchAgeDays>10");

盡管表達式樹將是一個可用的解決方案,但這種形式的詳細程度較低,可讀性更高,總體上實現起來工作量也少得多,並且允許將多個子句合並為對Where的單個調用。

https://github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM