如何使用LINQ Contains(string [])而不是Contains(string)

时间:2008-10-12 01:14:30

标签: c# linq string contains

我有一个大问题。

我有一个linq查询,看起来像这样:

from xx in table
where xx.uid.ToString().Contains(string[])
select xx

string[]数组的值将是(1,45,20,10等等)数字

.Contains的默认值为.Contains(string)

我需要它来代替:.Contains(string[]) ...

编辑:一位用户建议为string[]编写扩展程序。我想知道如何,但任何一个愿意指出我正确方向的人?

编辑: uid也是一个数字。这就是它被转换为字符串的原因。

帮助任何人?

22 个答案:

答案 0 :(得分:76)

spoulson几乎是正确的,但您需要先从List<string>创建一个string[]。实际上,如果uid也是List<int>int会更好。 List<T>支持Contains()。执行uid.ToString().Contains(string[])意味着作为字符串的uid包含数组的所有值作为子字符串???即使你确实写了扩展方法,它的意义也是错误的。

<强> [编辑]

除非你改变了它并为Mitch Wheat演示的string[]写了它,否则你只能跳过转换步骤。

[ENDEDIT]

如果您不使用扩展方法,那么这就是您想要的(除非您已经将潜在的uid集合作为整数 - 然后只使用List<int>())。这使用了链式方法语法,我认为它更清晰 转换为int以确保查询可以与更多提供程序一起使用。

var uids = arrayofuids.Select(id => int.Parse(id)).ToList();

var selected = table.Where(t => uids.Contains(t.uid));

答案 1 :(得分:31)

如果你真的想要复制 Contains ,但是对于一个数组,这里有一个extension method以及用法的示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ContainsAnyThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            string testValue = "123345789";

            //will print true
            Console.WriteLine(testValue.ContainsAny("123", "987", "554")); 

            //but so will this also print true
            Console.WriteLine(testValue.ContainsAny("1", "987", "554"));
            Console.ReadKey();

        }
    }

    public static class StringExtensions
    {
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) || values.Length > 0)
            {
                foreach (string value in values)
                {
                    if(str.Contains(value))
                        return true;
                }
            }

            return false;
        }
    }
}

答案 2 :(得分:17)

尝试以下方法。

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));

答案 3 :(得分:15)

.NET 4.0中的LINQ为您提供了另一种选择; .Any()方法;

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);

答案 4 :(得分:6)

或者如果您已经将数据放在列表中并且更喜欢其他Linq格式:)

List<string> uids = new List<string>(){"1", "45", "20", "10"};
List<user> table = GetDataFromSomewhere();

List<user> newTable = table.Where(xx => uids.Contains(xx.uid)).ToList();

答案 5 :(得分:3)

怎么样:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx

答案 6 :(得分:2)

这是编写扩展方法的一种方式的示例(注意:我不会将它用于非常大的数组;另一种数据结构更合适......):

namespace StringExtensionMethods
{
    public static class StringExtension
    {
        public static bool Contains(this string[] stringarray, string pat)
        {
            bool result = false;

            foreach (string s in stringarray)
            {
                if (s == pat)
                {
                    result = true;
                    break;
                }
            }

            return result;
        }
    }
}

答案 7 :(得分:2)

这是一个迟到的答案,但我相信它仍然有用 我创建了NinjaNye.SearchExtension nuget包,可以帮助解决这个问题。:

string[] terms = new[]{"search", "term", "collection"};
var result = context.Table.Search(terms, x => x.Name);

您还可以搜索多个字符串属性

var result = context.Table.Search(terms, x => x.Name, p.Description);

或者执行RankedSearch返回IQueryable<IRanked<T>>,其中只包含一个显示搜索字词出现次数的属性:

//Perform search and rank results by the most hits
var result = context.Table.RankedSearch(terms, x => x.Name, x.Description)
                     .OrderByDescending(r = r.Hits);

项目GitHub页面有更广泛的指南:https://github.com/ninjanye/SearchExtensions

希望这有助于未来的访客

答案 8 :(得分:1)

我相信你也可以这样做。

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx

答案 9 :(得分:1)

Linq扩展方法。将适用于任何IEnumerable对象:

    public static bool ContainsAny<T>(this IEnumerable<T> Collection, IEnumerable<T> Values)
    {
        return Collection.Any(x=> Values.Contains(x));
    }

用法:

string[] Array1 = {"1", "2"};
string[] Array2 = {"2", "4"};

bool Array2ItemsInArray1 = List1.ContainsAny(List2);

答案 10 :(得分:0)

HTTPResponse

答案 11 :(得分:0)

var SelecetdSteps = Context.FFTrakingSubCriticalSteps
             .Where(x => x.MeetingId == meetid)
             .Select(x =>    
         x.StepID  
             );

        var crtiticalsteps = Context.MT_CriticalSteps.Where(x =>x.cropid==FFT.Cropid).Select(x=>new
        {
            StepID= x.crsid,
            x.Name,
            Checked=false

        });


        var quer = from ax in crtiticalsteps
                   where (!SelecetdSteps.Contains(ax.StepID))
                   select ax;

答案 12 :(得分:0)

尝试:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;

答案 13 :(得分:0)

检查此扩展方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ContainsAnyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            const string iphoneAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like...";

            var majorAgents = new[] { "iPhone", "Android", "iPad" };
            var minorAgents = new[] { "Blackberry", "Windows Phone" };

            // true
            Console.WriteLine(iphoneAgent.ContainsAny(majorAgents));

            // false
            Console.WriteLine(iphoneAgent.ContainsAny(minorAgents));
            Console.ReadKey();
        }
    }

    public static class StringExtensions
    {
        /// <summary>
        /// Replicates Contains but for an array
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) && values.Length > 0)
                return values.Any(str.Contains);

            return false;
        }
    }
}

答案 14 :(得分:0)

from xx in table
where xx.uid.Split(',').Contains(string value )
select xx

答案 15 :(得分:0)

我相信你真正想做的是: 让我们想象一个场景 你有两个数据库 他们有一张共同的产品表 并且您希望从“A”表中选择与“B”

共同的产品

使用包含的方法太复杂了 我们正在做的是一个交集,并且有一个叫做交集的方法

来自msdn的一个例子: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1

int [] numbers =(0,2,4,5,6,8,9); int [] numbersB =(1,3,5,7,8); var = commonNumbers numbersA.Intersect(numbersB);

我认为您需要的东西可以通过交叉点轻松解决

答案 16 :(得分:0)

我找到的最佳解决方案是继续在SQL中创建一个表格值函数来生成结果,例如::

CREATE function [dbo].[getMatches](@textStr nvarchar(50)) returns @MatchTbl table(
Fullname nvarchar(50) null,
ID nvarchar(50) null
)
as begin
declare @SearchStr nvarchar(50);
set @SearchStr = '%' + @textStr + '%';
insert into @MatchTbl 
select (LName + ', ' + FName + ' ' + MName) AS FullName, ID = ID from employees where LName like @SearchStr;
return;
end

GO

select * from dbo.getMatches('j')

然后,您只需将该函数拖到LINQ.dbml设计器中,然后像执行其他对象一样调用它。 LINQ甚至知道存储函数的列。我这样称呼它为

Dim db As New NobleLINQ
Dim LNameSearch As String = txt_searchLName.Text
Dim hlink As HyperLink

For Each ee In db.getMatches(LNameSearch)
   hlink = New HyperLink With {.Text = ee.Fullname & "<br />", .NavigateUrl = "?ID=" & ee.ID}
   pnl_results.Controls.Add(hlink)
Next

非常简单,并且在应用程序中真正发挥了SQL和LINQ的强大功能......当然,您可以为相同的效果生成任何表值函数!

答案 17 :(得分:0)

我设法找到一个解决方案,但不是一个很好的解决方案,因为它需要使用AsEnumerable()来返回数据库中的所有结果,幸运的是我在表中只有1k记录所以它不是真的很明显,但是这里。

var users = from u in (from u in ctx.Users
                       where u.Mod_Status != "D"
                       select u).AsEnumerable()
            where ar.All(n => u.FullName.IndexOf(n,
                        StringComparison.InvariantCultureIgnoreCase) >= 0)
            select u;

我的原帖如下:

  

你怎么反过来?我想要   做类似以下的事情   实体框架。

string[] search = new string[] { "John", "Doe" };
var users = from u in ctx.Users
            from s in search
           where u.FullName.Contains(s)
          select u;
     

我想要的是找到所有用户   他们的FullName包含所有的   “搜索”中的元素。我试过了   所有这些的不同方式的数量   没有为我工作。

     

我也试过

var users = from u in ctx.Users select u;
foreach (string s in search) {
    users = users.Where(u => u.FullName.Contains(s));
}
     

此版本仅查找那些   包含搜索中的最后一个元素   阵列。

答案 18 :(得分:0)

你应该反过来写,检查你的特权用户ID列表包含该行表的id:

string[] search = new string[] { "2", "3" };
var result = from x in xx where search.Contains(x.uid.ToString()) select x;

LINQ在这里表现得相当明亮,并将其转换为一个好的SQL语句:

sp_executesql N'SELECT [t0].[uid]
FROM [dbo].[xx] AS [t0]
WHERE (CONVERT(NVarChar,[t0].[uid]))
IN (@p0, @p1)',N'@p0 nvarchar(1),
@p1 nvarchar(1)',@p0=N'2',@p1=N'3'

基本上将'search'数组的内容嵌入到sql查询中,并在SQL中使用'IN'关键字进行过滤。

答案 19 :(得分:0)

我是否正确地假设uid是唯一标识符(Guid)?这只是一个可能情况的例子,还是你真的想找到一个匹配字符串数组的guid?

如果这是真的,你可能想真正重新考虑这整个方法,这似乎是一个非常糟糕的主意。您可能应该尝试将Guid与Guid匹配

Guid id = new Guid(uid);
var query = from xx in table
            where xx.uid == id
            select xx;

老实说,我无法想象将使用“contains”的字符串数组与Guid的内容进行匹配的情况会是一个好主意。首先,Contains()不保证Guid中的数字顺序,因此您可能会匹配多个项目。更不用说比较guid这种方式比直接做它更慢。

答案 20 :(得分:-1)

string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx

答案 21 :(得分:-2)

Dim stringArray() = {"Pink Floyd", "AC/DC"}
Dim inSQL = From alb In albums Where stringArray.Contains(alb.Field(Of String)("Artiste").ToString())
Select New With
  {
     .Album = alb.Field(Of String)("Album"),
     .Annee = StrReverse(alb.Field(Of Integer)("Annee").ToString()) 
  }