2015-04-02 34 views
0

我正在研究ASP .NET MVC 5 Web應用程序並試圖實現搜索功能。我有Renders具有大約14個屬性的實體,它們是many-to-manyone-to-one的關係。用戶使用複選框中選擇屬性,所以我的代碼是這樣的:突變linq查詢以返回所需結果

if (Request.QueryString["attr1"] != "") 
{ 
    // linq query that gets all the render according to the request 
    // to the database that gets converted to t-sql 
} 

我有幾個if語句像上面一個代碼,現在我已經修改了我這樣的代碼:

var loadedRenders = _db.Renders.Include(r => r.Images) 
        .Include(m => m.DisplayFormats) 
        .Include(m => m.DisplayMethods) 
        .Include(m => m.DominantColors) 
        .Include(m => m.DrapeTypes) 
        .Include(m => m.CeilingHeights) 
        .Include(m => m.RiggingTypes) 
        .Include(m => m.HardSets) 
        .Include(m => m.SoftSets) 
        .Include(m => m.BackDrops) 
        .Include(m => m.SeatingTypes) 
        .Include(m => m.StageTypes) 
        .Include(m => m.VenueType) 
        .Include(m => m.EventTypes) 
        .ToList(); 
if (Request.QueryString["attr1"] != "") 
{ 
    // query that filters the renders in loadedRenders using 
    // linq 
} 

查詢1:

renders = renders.Union(loadedRenders 
         Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList(); 

問題2:

renders = renders.Union(_db.Renders.Include(r => r.Images) 
        .Include(m => m.DisplayFormats) 
        .Include(m => m.DisplayMethods) 
        .Include(m => m.DominantColors) 
        .Include(m => m.DrapeTypes) 
        .Include(m => m.CeilingHeights) 
        .Include(m => m.RiggingTypes) 
        .Include(m => m.HardSets) 
        .Include(m => m.SoftSets) 
        .Include(m => m.BackDrops) 
        .Include(m => m.SeatingTypes) 
        .Include(m => m.StageTypes) 
        .Include(m => m.VenueType) 
        .Include(m => m.EventTypes) 
        .Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList(); 

問:

兩個查詢正在返回不同的結果,我想原因是因爲他們中的一個在T-SQL執行和Linq他們的,我不知道我是否正確,但我想問的是,有什麼方法可以使Query 1返回與Query 2相同的結果嗎?

回答

0

在查詢1您使用具有以下條件

.Where(r => r.ActivateRender == true) 

loadrenderes而在QUERY2你不要有可能造成差異的條件

+0

這並沒有什麼區別,因爲我的兩個查詢都有這個條件......檢查編輯 – 2015-04-02 07:06:11

+0

它在query2中,但是paranthesis是錯誤的。 – 2015-04-02 07:07:20

+0

檢查編輯,我從loadedRenders中刪除它,我認爲區別是因爲「Contains」...那可能嗎? – 2015-04-02 07:12:48

0

我會說這條線使其中的差別

.Where(r => r.ActivateRender == true) 

它存在於loadedRenders中,但不存在於查詢2中

的情況也存在於查詢,但只有當你把所有的a||b||c||...括號,然後添加&& r.ActivateRender適用於因operator precedence

最後的選擇 - 這應該幫助

0

更改查詢線2

.Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term) && r.ActivateRender))).ToList(); 

這樣:

.Where(r => term != null && (r.Title.Contains(term) || r.ClientName.Contains(term) || r.JobId == (term)) && r.ActivateRender)).ToList(); 

的不能夠改變的是將條件r.ActivateRender移出OR條件的假設。

+0

爲什麼我需要檢查這種情況兩次? 'r.ClientName.Contains(term)' – 2015-04-02 07:09:56

+0

複製時出錯啊。 – 2015-04-02 07:14:44

0

您可以在內存中應用過濾,而不是使用ToList()調用執行查詢。

var loadedRenders = _db.Renders.Include(r => r.Images) 
        .Include(m => m.DisplayFormats) 
        ... 
        .Include(m => m.EventTypes) 
        .AsQueryable(); // AsQueryable does not execute the query to sql as ToList would 

if (Request.QueryString["attr1"] != "") 
{ 
    // Where() will return IQueryable and the query will not be executed yet 
    loadedRenders = loadedRenders.Where(<apply filtering here for attr1>); 
} 

if (Request.QueryString["attr2"] != "") 
{ 
    loadedRenders = loadedRenders.Where(<apply filtering here for attr2>); 
} 

// This will then create sql with all the applied filters 
var concreteList = loadedRenders.ToList(); 
+0

但我有兩種函數正在使用'union',正如你上面看到的那樣,另一種函數沒有'union',所以它首先增加計數,然後根據請求減少計數。你認爲你的方法在這種情況下會起作用嗎? – 2015-04-02 07:25:45

+0

您可以使用predicatebuilder http://www.albahari.com/nutshell/predicatebuilder.aspx獲取Or效果而不是Where,因此您不必使用Union。 – 2015-04-02 07:40:50

+0

,因爲我需要根據某些屬性建立搜索並根據某些屬性構建搜索,這可能沒有意義,但這是客戶想要的,因此工會... – 2015-04-02 08:13:38