用于数组元素相似查询的LINQ

用于数组元素相似查询的LINQ,linq,arrays,linq-to-sql,Linq,Arrays,Linq To Sql,假设我有一个数组,我想对varchar执行LINQ查询,该查询返回在varchar中任何位置具有数组元素的任何记录 像这样的东西会很甜蜜 string[]industries={“airline”,“railway”} var query=来自联系人中的c,其中c.industry.LikeAnyElement(industries)选择c 有什么想法吗 from c in contracts where industries.Any(i => i == c.industry) se

假设我有一个数组,我想对varchar执行LINQ查询,该查询返回在varchar中任何位置具有数组元素的任何记录

像这样的东西会很甜蜜


string[]industries={“airline”,“railway”}

var query=来自联系人中的c,其中c.industry.LikeAnyElement(industries)选择c

有什么想法吗

from c in contracts 
where industries.Any(i => i == c.industry)
select c;

差不多吧。对集合使用any方法。

不幸的是,LIKE在LINQ to SQL中不受支持,如下所示:

为了解决这个问题,您必须编写一个存储过程,它将接受like语句中要使用的参数,然后从LINQ调用SQL


应该注意的是,一些答案建议使用Contains。这将不起作用,因为它会查看整个字符串是否与数组元素匹配。正在查找的是要包含在字段本身中的数组元素,类似于:

industry LIKE '%<element>%'
where c.Industry.Contains("airline") ||
      c.Industry.Contains("railroad") || ...
如果您知道数组的长度和元素的数量,那么您可以硬编码。如果没有,则必须基于数组和正在查看的字段创建表达式实例。

IEnumerable.Contains()
在中转换为SQL,如中所示:

WHERE 'american airlines' IN ('airline', 'railroad') -- FALSE
WHERE 'american airlines' LIKE '%airline%' -- TRUE
String.Contains()
,它转换为SQL类似%…%,如:

WHERE 'american airlines' IN ('airline', 'railroad') -- FALSE
WHERE 'american airlines' LIKE '%airline%' -- TRUE
如果您希望联系人的行业类似于(包含)任何给定行业,则需要将any()和String.contains()组合成如下内容:

string[] industries = { "airline", "railroad" };

var query = from c in contacts 
            where industries.Any(i => c.Industry.Contains(i))
            select c;
但是,像这样组合Any()和String.Contains()在LINQ to SQL中是不受支持的。如果给定行业的集合很小,您可以尝试以下方法:

industry LIKE '%<element>%'
where c.Industry.Contains("airline") ||
      c.Industry.Contains("railroad") || ...
或者(尽管通常不推荐)如果联系人集足够小,您可以将它们全部从数据库中取出,并使用contacts.AsEnumerable()或contacts.ToList()作为上述查询的源,将带有LINQ的筛选器应用于对象:

var query = from c in contacts.AsEnumerable()
            where industries.Any(i => c.Industry.Contains(i))
            select c;

这实际上是我在“”演示中使用的一个示例,用于在常规LINQ中很难做到的事情;据我所知,最简单的方法是手动编写谓词。我使用下面的示例(注意,它同样适用于
StartsWith
etc):

使用(var ctx=new NorthwindDataContext())
{
ctx.Log=Console.Out;
var数据=ctx.Customers.WhereTrueForAny(
s=>cust=>cust.CompanyName.Contains,
“a”、“de”、“s”)。ToArray();
}
// ...
公共静态类QueryableExt
{
公共静态可在任何地方查询(
这是可靠的消息来源,
函数选择器,
参数TValue[]值)
{
返回source.Where(BuildTrueForAny(选择器,值));
}
公共静态表达式构建Trueforany(
函数选择器,
参数TValue[]值)
{
如果(选择器==null)抛出新的ArgumentNullException(“选择器”);
如果(value==null)抛出新的ArgumentNullException(“值”);
if(values.Length==0)返回x=>true;
if(values.Length==1)返回选择器(值[0]);
var param=表达式参数(typeof(TSource),“x”);
Expression body=Expression.Invoke(选择器(值[0]),参数);
for(int i=1;i
如果您按照以下方式建立查询,它将起作用:

var query=来自contacts.AsEnumerable()中的c 选择c

query=query.Where(c=>(c.Industry.Contains(“航空公司”))| |(c.Industry.Contains(“铁路”))


如果参数airline和railway是用户输入,则只需以编程方式生成上面的字符串。事实上,这比我预想的要复杂一些。见文章-

我知道。。我的错。。一辆马车!=-数组中的每一项都使用1就可以了。实际上,LIKE在LINQ to SQL中得到了一定程度的支持。“where c.industry.Contains(“airline”)”工作并转换为“where c.industry LIKE'%airline%'。但他希望像任何给定的值一样,而不仅仅是一个.LINQ to SQL、LINQ to entications、LINQ to Objects?这会在LINQ to SQL中引发一个异常。它可以写为“where industries.Contains(c.industry)”,翻译为“c.industry in”('airline'、'railway')”,但他想要一个类似的比较。很好!(请输入至少10个字符。)