Linq 如何选择/筛选字符串列表中的子字符串?

Linq 如何选择/筛选字符串列表中的子字符串?,linq,expression-trees,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")

我有一个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);
List MyDomains=[获取列表的代码];
var x=(来自dc.Activities中的a)
其中a.推荐人!=空
&&a.referer.Trim().长度>0
&&!a.referer.Contains(“本地主机”)
&&a.SearchResults.Count()==0
orderby a.ID降序
选择一个选项(a)
.采取(20);
既然我已经排除了这一点,让我更好地解释一下。MyDomains是一个字符串列表;每一个都是我拥有的根域

a、 referer是一个字符串,包含一个来自我的一个网站的推荐人。注意:此字符串将包含子域、文件夹、文件和查询字符串

我想按MyDomains列表中a.Referer的根域筛选x。也就是说,我希望以这种方式返回所有不匹配的记录。结果集应该最终包含引用者不是我的域之一的活动

我一直在学习Lambda表达式,但到目前为止,还不能设计一个表达式来实现这个目标,因为它实际上需要一个包含逻辑的where子句(可能是循环、子字符串等)

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

撇开架构上的分歧不谈,如何在LINQ查询中实现这一点


编辑:注意,我希望在查询中执行此操作,以便在添加.Take(20)之前删除匹配的记录。我希望每次都能得到相同数量的结果,而不必调用数据库获取更多信息。

我认为

&& !MyDomains.Contains(a.Referrer)
你应该做这个把戏

我认为

&& !MyDomains.Contains(a.Referrer)

如果我理解正确,你应该做这个把戏。你想获得前20个活动,按ID排序,其referer字段不包含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子句

更新:事实上,这是行不通的。由于查询表达式是在实际查询时进行计算的,因此除子句外的所有
子句对
变量使用相同的值(这是最后一个值集)

我所能想到的唯一解决方案是通过友好方式生成一个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);
var where子句=新列表();
对于(inti=0;i string.Format(“%$0}%”,d)).ToArray();
var sqlCommand=string.Format(
“从活动中选择前20个*,其中(非推荐人为空)和(非({0}))按Id排序”,
sqlFormattedDomains.Join(“或”);
var x=dc.ExecuteQuery(sqlCommand,sqlFormattedDomains);

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

如果我理解正确,您希望获得按ID排序的前20个活动,其Referrer字段不包含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子句

更新:事实上,这是行不通的。由于查询表达式是在实际查询时进行计算的,因此除
子句外的所有
子句对
变量使用相同的值(这是最后一个值集)

我所能想到的唯一解决方案是通过友好方式生成一个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);
var where子句=新列表();
对于(inti=0;i string.Format(“%$0}%”,d)).ToArray();
var sqlCommand=string.Format(
“从活动中选择前20个*,其中(非推荐人为空)和(非({0}))按Id排序”,
sqlFormattedDomains.Join(“或”);
var x=dc.ExecuteQuery(sqlCommand,sqlFormattedDomains);

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

不,引用者将是一个完整格式的URL,而MyDomains只是根域。{a.com,b.com}不包括{}。不,引用者将是一个完整格式的URL,而MyDomains只是根域。{a.com,b.com}不包括{}。不,foreach的每次迭代都会覆盖上一次迭代,而不是对其进行补充,因此我只计算列表中的最后一项+一个好主意,我提出的替代方案行吗?不行,foreach的每次迭代都会覆盖上一次迭代,而不是对其进行补充,因此我只计算列表中的最后一项+这是个好主意。我提出的替代方案行吗?