106

我有一个大问题。

我得到了一个 linq 查询,它看起来像这样:

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

数组的值string[]将是像 (1,45,20,10,etc...) 这样的数字

默认.Contains.Contains(string).

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

编辑:一位用户建议为string[]. 我想学习如何,但有人愿意为我指出正确的方向吗?

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

帮助任何人?

4

22 回答 22

89

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

[编辑]

除非你改变它并按照 Mitch Wheat 演示的那样编写它string[],否则你就可以跳过转换步骤。

[结束编辑]

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

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

var selected = table.Where(t => uids.Contains(t.uid));
于 2008-10-12T02:01:14.073 回答
40

如果你真的想复制Contains,但对于数组,这里有一个扩展方法和使用示例代码:

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;
        }
    }
}
于 2008-10-12T16:00:38.077 回答
23

试试下面的。

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
于 2008-10-12T02:03:25.987 回答
17

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

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
于 2012-03-14T22:40:46.867 回答
8

或者,如果您已经在列表中有数据并且更喜欢其他 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();
于 2011-04-28T03:31:53.450 回答
3

怎么样:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
于 2008-10-12T01:24:42.120 回答
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;
        }
    }
}
于 2008-10-12T01:54:24.057 回答
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);

或者执行一个RankedSearchwhich 返回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

希望这对未来的访客有所帮助

于 2014-02-13T09:07:50.043 回答
2

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);
于 2014-04-17T03:55:57.203 回答
1

我相信你也可以做这样的事情。

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx
于 2008-10-12T01:59:43.077 回答
0

那么我是否正确地假设 uid 是唯一标识符(Guid)?这只是可能场景的一个示例,还是您真的试图找到与字符串数组匹配的 guid?

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

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

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

于 2008-10-12T16:38:52.007 回答
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'关键字进行过滤。

于 2009-01-19T05:17:38.043 回答
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;

我想要的是找到他们的全名包含“搜索”中所有元素的所有用户。我尝试了许多不同的方法,所有这些方法都没有为我工作。

我也试过

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

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

于 2009-07-17T09:21:21.017 回答
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 的强大功能……当然,您可以生成任何您想要的表值函数以获得相同的效果!

于 2010-06-18T18:52:59.743 回答
0

我相信你真正想做的是:让我们想象一个场景,你有两个数据库,它们有一个共同的产品表,你想从表“A”中选择 id 与“B”相同的产品

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

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

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

我认为你需要的东西很容易通过交集来解决

于 2010-08-04T03:22:02.643 回答
0
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx
于 2012-07-30T07:02:35.737 回答
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;
        }
    }
}
于 2012-08-10T13:55:19.457 回答
0

尝试:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
于 2015-08-08T13:17:40.310 回答
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;
于 2019-03-06T11:05:11.400 回答
0
        string texto = "CALCA 40";
        string[] descpart = texto.Split(' ');

        var lst = (from item in db.InvItemsMaster
                   where descpart.All(val => item.itm_desc.Contains(val))
                   select item
                    ).ToList();
        Console.WriteLine("ITM".PadRight(10) + "DESC".PadRight(50)+"EAN".PadRight(14));
        foreach(var i in lst)
        {
           

            Console.Write(i.itm_id.ToString().PadRight(10));
            Console.Write(i.itm_desc.ToString().PadRight(50));
            Console.WriteLine(i.itm_ean.ToString().PadRight(14));


        }

        Console.ReadKey();
于 2020-08-20T02:28:03.427 回答
-1
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
于 2010-08-31T17:48:41.557 回答
-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()) 
  }
于 2016-10-16T18:21:00.393 回答