如何在字符串列表中选择/过滤子字符串?

时间:2009-11-05 05:43:47

标签: linq expression-trees

我有一个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到我的某个网站的引荐来源。请注意,此字符串将包含子域,文件夹,文件和查询字符串。

我想通过位于MyDomains列表中的a.Referrer的根域过滤x。也就是说,我希望以这种方式返回所有不匹配的记录。结果集应该最终包含其Referler不是我的域之一的活动。

我一直在学习Lambda表达式,但到目前为止还没有能够设法实现这个目标,因为它实际上需要一个带有逻辑的where子句(可能是循环,子串等)。

目前我正在考虑将X转换为List,手动过滤它们,然后将列表绑定到目标控件而不是绑定X.我有一个扩展方法来获取Uri的根域,另一个确定是否它是我的域名,但不能将它们放在Lambda中,因为它们“没有支持的SQL转换”。

除了建筑上的分歧之外,我如何在LINQ查询中实现这一点?


编辑:注意我想在查询中执行此操作,因此在添加.Take(20)之前删除匹配的记录。我希望每次都能获得相同数量的结果,而无需再调用数据库。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您希望获得按ID排序的前20个活动,其推荐人字段不包含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查询,因为将为MyDomains中的每个项添加一个WHERE子句。

更新:确实,这不起作用。由于查询表达式在实际查询时被计算,因此所有Except子句对domain变量使用相同的值(这是最后一个值集)。

我能想到的唯一解决方案是动态生成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);

您必须扩展SearchResults.Count() == 0条件的SQL命令,我想这与将join子句添加到另一个表有关。

答案 1 :(得分:0)

我认为添加

&& !MyDomains.Contains(a.Referrer)

应该做的伎俩