【问题标题】:How to use Linq to check if string property contains any of string in a list collection如何使用 Linq 检查字符串属性是否包含列表集合中的任何字符串
【发布时间】:2016-04-10 19:49:39
【问题描述】:

我有以逗号分隔的电子邮件列表

var emails="a@gmail.com,b@gmail.com,c@gmail.com,d@gmail.com,e@gmail.com,";
var list=new List<string>();
list.Add("c@gmail.com");
list.Add("d@gmail.com");

我如何编写 ling 查询来确定字符串(电子邮件)是否有任何电子邮件地址匹配 集合(列表)。

我正在使用 EF,电子邮件字符串是类中的属性,列表是独立集合。

【问题讨论】:

  • 您是说emails 实际上是您使用 EF 查询的实体的属性吗?
  • 是的@juharr 电子邮件是实体的财产
  • 那么你真的应该考虑不要将逗号分隔的列表作为一个字符串存储在你的数据库中,而是创建一个适当的一对多关系。
  • 我真的无法更改数据库。这是要求。
  • 重要的是告诉我们您到目前为止的尝试。

标签: c# entity-framework linq list contains


【解决方案1】:
emails.Split(',').Any(e=>list.Contains(e));

或者:

emails.Split(',').Intersect(list).Any();

如果您使用它来查找数据库记录,那么您可以这样做:

db.MyTable.Where(l=>list.Any(e=>l.emails.StartsWith(e+",")) ||
list.Any(e=>l.emails.EndsWith(","+e)) ||
list.Any(e=>l.emails.Contains(","+e+",")) ||
list.Any(e=>l.emails==e)
)

或者你可以简化它:

db.MyTable.Where(l=>list.Any(e=>(","+l.emails+",").Contains(","+e+",")))

如果您正在查找第一条记录,第 3 个选项可能会执行得更好,因为它可能会使用您在电子邮件中的任何索引来快速定位记录,但如果列表很大,它将生成一些非常大的 SQL 语句(当前实现不幸的是,SQL LINQ 提供程序将其转换为 CHARINDEX 函数而不是 LIKE 'email%',但这可能会改变)。

第 4 个选项将生成更简单的 SQL,如果要查找所有匹配的记录而不是第一个匹配记录,则可能会执行得更好。

【讨论】:

  • 您将需要emails.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries),因为电子邮件列表中的尾随,
  • @MatthewWatson 仅当您想假设空字符串匹配无效时,我不会做出这样的假设。如果你不想匹配一个空字符串,那么不要在list中放入一个空字符串。
  • 但是string.Contains(text, "")总是会返回true,而且邮件列表后面有,所以如果拆分后不删除空条目,不管@的内容如何,​​结果都是true 987654330@.
  • @MatthewWatson 但我从不这样做string.Contains(text,"")。前两个是List&lt;string&gt;.Contains(string),所以它正在寻找一个完全匹配的元素。当您第一次回复时,第三个(和第四个)不存在,并且仍然没有表现出您描述的行为。
  • @MatthewWatson ["ABC","DEF",""].Contains("something") 返回 false。
【解决方案2】:
var emailsList = emails.Split(',');
list.Any( x => emailsList.Contains(x));

另一种方法

  HashSet<String> emailSet = New HashSet<String>(temp.Split(","));
  list.Any(s => emailSet.Contains(s, StringComparer.Ordinal));

使用 HashSet - Contains 工作得更快(如果电子邮件字符串可能很大)并删除重复项 并比较 stringg 区分大小写而不创建新字符串 ToLower()

【讨论】:

  • 那里的x = 不会编译。
【解决方案3】:

您可以按照以下方式进行

emails.Split(',').Any (y => list.Contains (y));

【讨论】:

    【解决方案4】:

    此解决方案使用 linq。因为您的电子邮件地址以逗号分隔(并以逗号结尾),我们可以检查列表中的 Any() 项目是否包含在电子邮件字符串中。我使用 ToLower() 使其不区分大小写(通常是电子邮件地址)。

    var hasMatch = list.Any(item => ","+emails.ToLower().Contains(","+item.ToLower()+","));
    

    【讨论】:

    • 感谢@Fann,这是我能想到的一种解决方案。
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 2021-12-11
    • 2021-11-26
    • 2016-01-27
    • 2023-03-14
    • 2014-10-07
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多