2009-11-05 72 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