2009-11-05 188 views
1

我有一個LINQ結果集我試圖以奇怪和奇特的方式過濾。如何選擇/篩選字符串列表中的子字符串?

List<string> MyDomains = [Code to get list]; 

var x = (from a in dc.Activities 
    where a.Referrer != null 
     && a.Referrer.Trim().Length > 0 
     && !a.Referrer.Contains("localhost") 
     && a.SearchResults.Count() == 0 
    orderby a.ID descending 
    select a) 
    .Take(20); 

既然我已經這樣做,讓我更好地解釋它。 MyDomains是一個字符串列表;每一個都是我擁有的根域。

a.Referrer是包含來自GET引薦到我的網站之一的字符串。請注意,此字符串將包含子域,文件夾,文件和查詢字符串。

我想a.Referrer的根域在MyDomains名單是過濾X。也就是說,我想要以這種方式返回所有不匹配的記錄。結果集最終應包含「推薦人」不屬於我的域的活動。

我一直在學習Lambda表達式,但因爲它有效地需要在那裏與裏面的邏輯子句到目前爲止還沒有能夠工藝之一,實現這一目標(可能循環,子等)。

目前我在考慮將X轉換爲列表,手動過濾它們,然後將列表綁定到目標控件而不是綁定X.我有一個擴展方法來獲取Uri的根域,另一個方法來確定無論它是我的域名,但不能將它們放入Lambda中,因爲它們「沒有支持到SQL的轉換」。

建築分歧放在一邊,我怎麼能完成這個從我的LINQ查詢中?


編輯:注意我想從查詢中這樣做,所以我添加.Take(20)之前刪除匹配的記錄。我希望每次都能獲得相同數量的結果,而無需再爲數據庫調用更多的結果。

回答

1

如果我理解正確的話,你想獲得前20名的活動,通過ID,其推薦人字段不包含任何的排序MyDomains中的項目作爲子字符串。

以下,或者類似的東西,應該工作:

var theActivities = (from a in dc.Activities 
    where a.Referrer != null 
     && a.Referrer.Trim().Length > 0 
     && a.SearchResults.Count() == 0 
    select a); 

foreach(var domain in MyDomains) { 
    theActivities = theActivities.Except(dc.Activities.Where(a => a.Referrer.Contains(domain))); 
} 

theActivities = theActivities.OrderBy(a => a.Id).Take(20); 

//Now you can query theActivities 

不過請注意,你會最終有一個相當長的SQL查詢,因爲WHERE子句將在MyDomains每個項目加入。

UPDATE:的確,這是不行的。由於查詢表達式在實際查詢時被評估,所有Except子句對domain變量(這是最後一個值集合)使用相同的值。

我能想到那麼唯一的解決辦法,就是dinamically生成SQL命令來獲取數據。我也沒有辦法,現在來驗證碼,但它是大約是這樣的:

var whereClauses=new List<string>(); 

for(int i=0; i<MyDomains.Length; i++) { 
    whereClauses.Add(string.Format("(Referrer like {{{0}}})", i)); 
} 

var sqlFormattedDomains=MyDomains.Select(d => string.Format("%{0}%", d)).ToArray(); 

var sqlCommand=string.Format(
    "select top 20 * from Activities where (not Referrer is null) and (not ({0})) order by Id", 
    sqlFormattedDomains.Join(" or ")); 

var x=dc.ExecuteQuery<Activities>(sqlCommand, sqlFormattedDomains); 

你將不得不展開SQL命令爲SearchResults.Count() == 0條件,我想,這與添加一個連接做子句到另一個表。

+0

不,每次foreach的迭代都會覆蓋前面的內容而不是補充它,所以我最終只列出了正在計數的列表中的最後一項。 +1一個不錯的主意壽。 – tsilb 2009-11-05 20:00:33

+0

我提出的替代解決方案好嗎? – Konamiman 2009-11-09 10:20:20

0

我認爲,加入

&& !MyDomains.Contains(a.Referrer) 

應該做的伎倆

+0

不可以,推薦人將是一個完整的URL,而MyDomains只是根域。 {a.com,b.com}不包含{http://www.a.com/folder/file.htm?c=d&e=f}。 – tsilb 2009-11-05 18:49:54

+0

好吧,讓事情變得有趣一點,然後...... – Murph 2009-11-05 21:10:26