2010-06-08 5 views
3

Comment puis-je générer des caractères génériques dans mon expression LINQ To SQL lambda?LINQ to SQL Wildcards

C'est ce que j'ai actuellement:

var query = from log in context.Logs select log; 
foreach (string filter in CustomReport.ExtColsToFilter) 
{ 
    string tempFilter = filter; 
    query = query.Where(Log => Log.FormattedMessage.Contains(tempFilter)); 
} 

Cela fonctionne bien jusqu'à ce que j'essaie de passer des caractères génériques dans la chaîne de filtre. J'expérimente avec SqlMethods.Like() mais en vain. Les filtres ci-dessus ressemblent à ceci: "<key>NID</key><value>mcass</value>".

Je voudrais être en mesure de passer les filtres comme ceci: "<key>NID</key><value>%m%</value>"

+1

'SqlMethods.Like' devrait fonctionner. Quel est le résultat lorsque vous l'essayez? – Thorarin

+0

@Thorarin Le SQL résultant est le même que le .Contains() SQL. Peut-être que je dois me concentrer davantage sur l'incorporation de caractères génériques? – mcass20

+0

juste pour être clair, passez-vous à '" NID% m% "' à 'SqlMethods.Like' et obtenez toujours le même résultat que vous étiez sans les caractères génériques'% '? –

Répondre

8

String.Contains est effectivement mis en œuvre comme une expression LIKE dans LINQ to SQL, de sorte que ces requêtes seraient équivalentes:

query = query.Where(Log => Log.FormattedMessage.Contains("m")); 
query = query.Where(Log => SqlMethods.Like(Log.FormattedMessage, "%m%")); 

Cependant, avec SqlMethods.Like, vous pouvez spécifier des modèles plus complexes, tels que "%m%a%". Fonctionne bien pour moi. Vous ne pouvez pas vraiment voir la différence depuis l'intérieur de Visual Studio, car l'expression à comparer est placée dans un paramètre du T-SQL.

Si vous deviez connecter la requête SQL dans un profileur, il ressemblerait à quelque chose comme ceci:

exec sp_executesql N'SELECT [t0].[ID], [t0].[FormattedMessage] 
FROM [dbo].[Log] AS [t0] 
WHERE [t0].[FormattedMessage] LIKE @p0',N'@p0 nvarchar(5)',@p0=N'%m%a%' 

Ne concerne pas la question en soi, mais String.StartsWith et String.EndsWidth traduisent également un SQL LIKE, avec des modèles légèrement différents bien sûr.

+0

Merci pour votre contribution. Je commence à penser que mon problème réside dans les filtres eux-mêmes.Si vous regardez le bas de ma question, je donne aux chaînes que je demande. Le premier renvoie un enregistrement. La seconde, non. Si cela aide, j'interroge une colonne SQL qui contient xml semblable à mes exemples de filtre. – mcass20

+0

@ mcass20: C'est très étrange. Si le premier filtre renvoie un enregistrement, le second filtre devrait définitivement revenir à * un * minimum. Si vous avez SQL Profiler, il peut être utile de comprendre ce qui se passe. – Thorarin

+0

Si vous n'avez pas SQL Profiler, attacher 'Console.Out' (ou un autre TextWriter) à' context.Log' fonctionnerait aussi, bien sûr. – Thorarin

0

Le caractère générique est telle que, m *, donc tout avec un m, pour le caractère générique, vous pouvez demander si elle .Contains (m) ; et il obtiendra n'importe quoi contenant 'm'.

Si vous avez besoin générique dans le sens de tous les résultats de cette table, il suffit d'utiliser

query.ToList(); 

Vous avez maintenant la liste complète des journaux.

Espérons que ça aide.

+0

Si vous avez besoin de plusieurs chaînes, vous pouvez utiliser l'instruction ForEach, vérifier chaque chaîne et la placer dans une liste locale avec chaque chaîne. "Liste Règles = new Liste (); var Logs = new Liste (); Rules.ForEach (règle => Logs.Add (query.Contains (règle)));" Je crois que cela devrait fonctionner! –