Как использовать LINQ Contains (строка []) вместо Contains (строка) - PullRequest
85 голосов
/ 12 октября 2008

У меня один большой вопрос.

Я получил запрос 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 также будет число. Вот почему он преобразуется в строку.

Помогите кому-нибудь?

Ответы [ 21 ]

0 голосов
/ 17 июля 2009

Мне удалось найти решение, но не очень удачное, так как оно требует использования 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));
}

Эта версия находит только те, которые содержать последний элемент в поиске массив.

0 голосов
/ 10 августа 2012

Проверьте этот метод расширения:

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;
        }
    }
}
0 голосов
/ 30 июля 2012
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx
0 голосов
/ 12 октября 2008

Итак, я правильно предполагаю, что 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, поэтому вы потенциально можете сопоставить несколько элементов. Не говоря уже о том, что сравнивать направляющие таким образом будет гораздо медленнее, чем просто делать это напрямую.

0 голосов
/ 31 августа 2010
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
0 голосов
/ 16 октября 2016
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()) 
  }
0 голосов
/ 19 января 2009

Вы должны написать это наоборот, проверив, что ваш список идентификаторов привилегированных пользователей содержит идентификатор в этой строке таблицы:

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 и выполняет фильтрацию по ключевому слову IN в SQL.

0 голосов
/ 08 августа 2015

Попробуйте:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
0 голосов
/ 18 июня 2010

Лучшее решение, которое я нашел, было пойти дальше и создать табличную функцию в 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 в приложении ... и вы, конечно, можете сгенерировать любую табличную функцию, какую захотите, для того же эффекта!

0 голосов
/ 06 марта 2019
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;
...