Question

J'ai une grande question.

J'ai une requête linq pour le dire qui ressemble à ceci:

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

Les valeurs du tableau string[] seraient des nombres tels que (1,45,20,10, etc ...)

la valeur par défaut pour .Contains est .Contains(string).

J'en ai besoin pour faire ceci à la place: .Contains(string[]) ...

EDIT: un utilisateur a suggéré d'écrire une classe d'extension pour <=>. Je voudrais savoir comment, mais vous êtes prêt à me diriger dans la bonne direction?

MODIFIER: L'UID serait également un nombre. C'est pourquoi il est converti en chaîne.

Aidez-vous quelqu'un?

Était-ce utile?

La solution

spoulson a presque raison, mais vous devez d’abord créer un List<string> à partir de string[]. En fait, un List<int> serait mieux si uid est aussi int. List<T> prend en charge Contains(). Faire uid.ToString().Contains(string[]) impliquerait que l'uid en tant que chaîne contienne toutes les valeurs du tableau en tant que sous-chaîne ??? Même si vous aviez écrit la méthode d'extension, vous auriez tort de la comprendre.

[MODIFIER]

À moins que vous ne l'ayez modifié et écrit pour List<int>() comme le montre Mitch Wheat, vous pourrez alors ignorer l'étape de conversion.

[ENDEDIT]

Voici ce que vous voulez, si vous ne faites pas la méthode d'extension (à moins que vous ne possédiez déjà la collection des uids potentiels en tant qu'ints - utilisez simplement <=> à la place). Cela utilise la syntaxe de la méthode chaînée, qui, je pense, est plus propre, et effectue la conversion en int pour garantir que la requête peut être utilisée avec plus de fournisseurs.

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

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

Autres conseils

Si vous souhaitez vraiment répliquer Contains , voici un méthode d'extension et exemple de code d'utilisation:

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;
        }
    }
}

Essayez ce qui suit.

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

LINQ dans .NET 4.0 a une autre option pour vous; la méthode .Any ();

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

Ou si vous avez déjà les données dans une liste et préférez l'autre format 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();

Que diriez-vous de:

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

Voici un exemple de méthode d'écriture d'une méthode d'extension (note: je ne l'utiliserais pas pour de très grands tableaux; une autre structure de données serait plus appropriée ...):

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;
        }
    }
}

C'est une réponse tardive, mais je pense que cela reste utile .
J'ai créé le package NinjaNye.SearchExtension qui peut vous aider à résoudre ce problème.: p>

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

Vous pouvez également rechercher plusieurs propriétés de chaîne

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

Ou effectuez un RankedSearch qui retourne IQueryable<IRanked<T>> et qui inclut simplement une propriété indiquant le nombre de fois que les termes de recherche sont apparus:

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

La page des projets GitHub contient un guide plus complet: https://github.com/ninjanye/SearchExtensions

J'espère que cela aidera les futurs visiteurs

Je pense que vous pourriez aussi faire quelque chose comme ça.

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

Méthode d'extension Linq. Travaillera avec n'importe quel objet IEnumerable:

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

Utilisation:

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

bool Array2ItemsInArray1 = List1.ContainsAny(List2);

Alors, est-ce que je suppose correctement que uid est un identifiant unique (Guid)? S'agit-il d'un exemple de scénario possible ou essayez-vous réellement de trouver un GUID correspondant à un tableau de chaînes?

Si cela est vrai, vous voudrez peut-être vraiment repenser toute cette approche, cela semble être une très mauvaise idée. Vous devriez probablement essayer de faire correspondre un Guid à un Guid

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

Honnêtement, je ne peux pas imaginer un scénario où la mise en correspondance d'un tableau de chaînes à l'aide de " contient " au contenu d'un Guid serait une bonne idée. D'une part, Contains () ne garantit pas l'ordre des nombres dans le Guid afin que vous puissiez potentiellement faire correspondre plusieurs éléments. Sans parler de comparer les astuces de cette façon serait bien plus lent que de le faire directement.

Vous devriez l'écrire dans l'autre sens, en vérifiant que votre liste d'identifiants d'utilisateurs privilégiés contient l'identifiant sur cette ligne de la table:

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

LINQ se comporte ici très bien et le convertit en une bonne instruction 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'

qui incorpore fondamentalement le contenu du tableau 'search' dans la requête SQL et effectue le filtrage avec le mot clé 'IN' en SQL.

J'ai réussi à trouver une solution, mais pas excellente, car elle nécessite l'utilisation de AsEnumerable (), qui va renvoyer tous les résultats de la base de données. Heureusement, je n'ai que 1k enregistrements dans la table, de sorte que ce n'est pas vraiment visible. mais voilà.

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;

Ma publication d'origine suit:

  

Comment faites-vous l'inverse? je veux   faire quelque chose comme ce qui suit dans   cadre d'entité.

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

Ce que je veux, c'est trouver tous les utilisateurs où   leur nom complet contient tous les   éléments dans `search '. J'ai essayé un   nombre de façons différentes, qui   ne travaillent pas pour moi.

     

J'ai aussi essayé

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

Cette version ne trouve que ceux qui   contient le dernier élément de la recherche   tableau.

La meilleure solution que j'ai trouvée consistait à créer une fonction à valeur de table en SQL produisant les résultats, tels que ::

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')

Ensuite, faites simplement glisser la fonction dans votre concepteur LINQ.dbml et appelez-la comme vous le feriez avec vos autres objets. Le LINQ connaît même les colonnes de votre fonction stockée. Je l'appelle comme ça ::

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

Incroyablement simple, il exploite réellement la puissance de SQL et de LINQ dans l’application ... et vous pouvez bien sûr générer toute fonction table que vous voulez pour les mêmes effets!

Je crois que ce que vous voulez vraiment faire est: imaginons un scénario vous avez deux bases de données et ils ont une table de produits en commun Et vous voulez sélectionner des produits dans le tableau & Quot; A & Quot; cet identifiant a en commun avec le & "B &";

utiliser la méthode contient serait trop compliqué pour le faire ce que nous faisons est une intersection, et il existe une méthode appelée intersection pour cette

un exemple de msdn: http://msdn.microsoft.com/en-us/vcsharp/ aa336761.aspx # intersect1

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

Je pense que ce dont vous avez besoin est facilement résolu avec l'intersection

Vérifiez cette méthode d'extension:

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;
        }
    }
}
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx

Essayez:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
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;
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
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()) 
  }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top