LINQ to SQL - 选择文本之类的字符串数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/512285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ to SQL - select where text like string array
提问by bjallen
I have a List<string
> of variable count, and I want to query (via LINQ) a table to find any items that contain any of those strings in the Text column.
我有一个 List <string
> of variable count,我想查询(通过 LINQ)一个表以查找包含 Text 列中任何这些字符串的任何项目。
Tried this (doesn't work):
试过这个(不起作用):
items = from dbt in database.Items
where (stringList.FindAll(s => dbt.Text.Contains(s)).Count > 0)
select dbt;
Query would be something like:
查询将类似于:
select * from items where text like '%string1%' or text like '%string2%'
Is this possible?
这可能吗?
回答by Matthew Doyle
Check this article out to do what you want:
http://www.albahari.com/nutshell/predicatebuilder.aspx
This works like a dream. I essentially cut and pasted their code and got this back (with my own data-scheme of course):
看看这篇文章,做你想做的事:
http://www.albahari.com/nutshell/predicatebuilder.aspx
这就像做梦一样。我基本上剪切并粘贴了他们的代码并将其取回(当然还有我自己的数据方案):
SELECT [t0].[Id], [t0].[DateCreated], [t0].[Name] ...
FROM [dbo].[Companies] AS [t0]
WHERE ([t0].[Name] LIKE @p0) OR ([t0].[Name] LIKE @p1)
Here is the code I ran for the proof of concept:
这是我为概念验证运行的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace PredicateTest
{
class Program
{
static void Main(string[] args)
{
DataClasses1DataContext dataContext = new DataClasses1DataContext();
Program p = new Program();
Program.SearchCompanies("test", "test2");
var pr = from pi in dataContext.Companies.Where(Program.SearchCompanies("test", "test2")) select pi;
}
DataClasses1DataContext dataContext = new DataClasses1DataContext();
public static Expression<Func<Company, bool>> SearchCompanies(
params string[] keywords)
{
var predicate = PredicateBuilder.False<Company>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or(p => p.Name.Contains(temp));
}
return predicate;
}
}
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
}
}
I'd suggest going to the site for the code and explanation.
我建议去该网站获取代码和解释。
(I am leaving the first answer because it works well if you need an IN statement)
(我将留下第一个答案,因为如果您需要 IN 语句,它可以很好地工作)
回答by Matthew Doyle
kind of new to the whole LINQ to SQL game, but does this syntax help?
对整个 LINQ to SQL 游戏来说有点新,但是这种语法有帮助吗?
string[] items = new string[] { "a", "b", "c", "d" };
var items = from i in db.Items
where items.Contains(p.text)
select i;
Got it from:
从:
http://blog.wekeroad.com/2008/02/27/creating-in-queries-with-linq-to-sql/
http://blog.wekeroad.com/2008/02/27/creating-in-queries-with-linq-to-sql/
回答by Slipdigital
After reading this post, looking for the same solution as you, I found a solution using the .Any
and .All
methods for Linq are a nice simple and elegant way to get matching results for arrays.
阅读这篇文章后,寻找与您相同的解决方案,我发现使用Linq的.Any
和.All
方法的解决方案是获得数组匹配结果的一种简单而优雅的方法。
In this instance I'm using a search input, separated by commas as an example. I don't care if the match is not in the same case.
在本例中,我使用了一个搜索输入,以逗号分隔作为示例。我不在乎比赛是否在同一情况下。
var qry = Query.Split(',').Select(c => c.Trim().ToLower());
First Get some data to query, from Linq to SQL or wherever
首先获取一些要查询的数据,从Linq 到SQL 或其他任何地方
var search = db.tablename;
Using the lambda syntax for nice tight code, and result in matches to .Any
string in the query to either the name or description in the table.
使用 lambda 语法编写漂亮的紧凑代码,并导致.Any
查询中的字符串与表中的名称或描述相匹配。
search = search.Where(
record =>
qry.Any(q => record.Name.ToLower().Contains(q)) ||
qry.Any(q => record.Description.ToLower().Contains(q)));
If you want only results where all strings are matched within any field you can replace .Any
with .All
:
如果您只想要在任何字段中匹配所有字符串的结果,您可以替换.Any
为.All
:
search = search.Where(
record =>
qry.All(q => record.Name.ToLower().Contains(q)) ||
qry.All(q => record.Description.ToLower().Contains(q)));
回答by Ali ?ncir
Using:
使用:
string searh = "test1 test2,test3";
data.Persons.Search(p => p.Name, search);
Search function is:
搜索功能是:
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string s)
{
if (string.IsNullOrEmpty(s))
return source;
string[] str = s.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
MethodInfo methodContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
Expression strExpression;
Expression expressionContains;
Expression resultExpression = Expression.Empty();
for (int i = 0; i < str.Length; i++)
{
strExpression = Expression.Constant(str[i].Trim(), typeof(string));
expressionContains = Expression.Call(selector.Body, methodContains, strExpression);
if (i == 0)
resultExpression = expressionContains;
else
resultExpression = Expression.OrElse(resultExpression, expressionContains);
}
Expression<Func<T, bool>> lambdaExpr = Expression.Lambda<Func<T, bool>>(resultExpression, new ParameterExpression[] { selector.Parameters[0] });
return source.Where(lambdaExpr);
}