LINQ在两个列表之间的包含性问题

3

我有一个字符串列表和一个供应商List<supplier>

字符串列表包含一些搜索项,而供应商列表包含供应商对象的列表。现在我需要找到与字符串List<string>中任何项匹配的所有供应商名称。

这是我的一个失败尝试..

var query = some join with the supplier table.
query = query.where(k=>stringlist.contains(k.companyname)).select (...).tolist();

有什么想法如何实现这个??
编辑:
也许我的问题没有表达清楚...我需要找到一个供应商列表(不仅仅是名称,整个对象),其中供应商名称与字符串列表中的任何项匹配。
如果我这样做
query = query.where(k=>k.companyname.contains("any_string")).select (...).tolist();

它可以工作。但这不是我的需求。 我的需求是一个字符串列表,而不是单个字符串。


查找它们的交集 - Jonesopolis
你的伪代码有什么问题,你只需要在选择中投影名称字段,它就应该可以工作了。 - Habib
这与linqtosql有什么关系? - Mark Homer
4个回答

8
以下查询将返回存在于名称列表中的唯一供应商名称:
suppliers.Where(s => stringlist.Contains(s.CompanyName))
         .Select(s => s.CompanyName) // remove if you need whole supplier object
         .Distinct();

生成的SQL查询语句将如下所示:

SELECT DISTINCT [t0].[FCompanyName]
FROM [dbo].[Supplier] AS [t0]
WHERE [t0].[CompanyName] IN (@p0, @p1, @p2)

顺便提一下,考虑使用更好的名称,例如companyNames而不是stringlist


我的代码不是和你的很相似吗?我只是没有那个明显的 "!!"。但在我的代码中,第一个查询返回1000个项目,在 where 之后它什么也不返回。但是,如果我使用单个字符串而不是字符串列表,它可以正常工作。 - Reza.Hoque
@kandroid 如果你需要整个供应商对象,即使是 suppliers.Where(s => stringlist.Contains(s.CompanyName)) 也可以完成工作。确保你真的有匹配的供应商。也许公司名称没有被修剪?另外,在你的第一个查询中,你检查公司名称是否完全匹配值。在你的工作示例中,你检查值是否包含在公司名称中。所以,如果你有值 org 和公司名称 Zorg,那么它将不匹配。但是你最后的查询将匹配,因此 org 包含在 Zorg 中。 - Sergey Berezovskiy
实际上,主要问题是query = query.where(k => stringlist.contains(k.companyname)).select (...).tolist(); 这里只会寻找完全匹配的结果……您知道如何使其能够像“like”一样工作吗? - Reza.Hoque
1
据我所知,对于本地序列(stringlist),Linq to SQL只能将Contains翻译成SQL。因此,为了使用like,您应该将过滤器移入内存(例如使用ToList):suppliers.ToList().Where(s => stringlist.Any(x => s.CompanyName.Contains(x)))。此查询将搜索所有公司名称类似于stringlist中某个值的公司。但请记住,将过滤器移入内存将加载所有公司到内存中。 - Sergey Berezovskiy
顺便提一下,实体框架可以将对本地集合的 Any 转换为 SQL 查询。 - Sergey Berezovskiy

5
你可以使用Intersect(交集)来实现这一功能(只匹配名称):

你可以访问Intersect了解更多信息。

var suppliersInBothLists = supplierNames
               .Intersect(supplierObjects.Select(s => s.CompanyName));

在您进行编辑后,对于供应商(不仅仅是名称):
var suppliers = supplierObjects.Where(s => supplierNames.Contains(s.CompanyName));

0
var matches = yourList.Where(x => stringList.Contains(x.CompanyName)).Select(x => x.CompanyName).ToList();

1
如果您能澄清您想要的内容和/或给出对象的确切名称,它实际上是有效的。我将进行编辑以显示如何仅选择名称。 - wilso132
@kandroid 根据您的编辑,我的原始答案正是您要寻找的。请检查编辑之前的版本。 - wilso132

0
要么像Tim建议的那样使用join,要么直接使用HashSet。这比在其他答案中使用List上的.Contains要高效得多。
var stringSet = new HashSet(stringList);
var result = query.Where(q => stringSet.Contains(q.Name));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接