2010-06-07 5 views
10

J'ai fait un peu de recherche à ce sujet et j'ai regardé quelques articles ici sur StackOverflow ainsi que quelques articles de blog, mais je n'ai pas trouvé de réponse exacte. J'ai également lu qu'il est possible de le faire en utilisant le cadre 4.0, mais je n'ai pas encore trouvé de preuves à l'appui.LINQ to SQL SOUNDEX - possible?

Donc, ma question, est-il possible d'effectuer SOUNDEX via une requête LINQ to SQL?

Répondre

20

Vous pouvez le faire à la base de données, en utilisant un faux UDF; dans une classe partielle, ajouter une méthode au contexte des données:

[DbFunction(Name = "SoundEx", IsComposable = true)] 
public string SoundsLike(string input) 
{ 
    throw new NotImplementedException(); 
} 

Vous pouvez l'utiliser comme une expression comme:

x => db.SoundsLike(x.QuoteValue) == db.SoundsLike("text") 

idée initiale à partir de: Random row from Linq to Sql

+2

Pour ceux qui ont essayé avec des versions plus récentes: (et pour ma propre référence future) [DbFunction ("SqlServer", "SOUNDEX")] –

2

C'est précisément ce qui est démontré dans "LINQ to Objects Using C# 4.0" par Troy Magennis.

EDIT: Ajout d'exemples de bits et de clarifications: l'exemple de l'auteur concerne LINQ to objects plutôt que LINQ to SQL. L'auteur a simplement fait un IEqualityComparer, quelques morceaux dont ressemblait à ceci ...

public class SoundexEqualityComparer : IEqualityComparer<string> 
{ 
    public bool Equals(string x, string y) 
    { 
    return GetHashCode(x) == GetHashCode(y); 
    } 

    public int GetHashCode(string obj) 
    { 
    //e.g. convert soundex code A123, 
    //to an integer: 65123 
    int result = 0; 

    string s = soundex(obj); 
    if (string.IsNullOrEmpty(s) == false) 
     result = Convert.ToInt32(s[0]) * 1000 + 
       Convert.ToInt32(s.Substring(1, 3)); 
    return result; 
    } 

    private string soundex(string s) 
    { 
    //e.g. book's implementation omitted for this post. 
    } 
} 

//example usage (assuming an array of strings in "names") 
var q = names.GroupBy(s => s, new SoundexEqualityComparer()); 
+4

Et pour ceux qui n'ont pas le livre, avez-vous un exemple? –

+2

Bien que je vous remercie pour la réponse Mystagogue, un exemple ou un lien vers un exemple serait plus bénéfique qu'un lien vers un livre que je peux acheter. –

0

Sur le serveur SQL, vous pouvez envelopper SOUNDEX dans une UDF (fonction définie par l'utilisateur). Vous pouvez l'ajouter à votre classe DataContext, puis vous devriez pouvoir l'utiliser via le DataContext.

+0

Seriez-vous en mesure de fournir un exemple de ceci s'il vous plaît? –

5

Ajouter un udf comme ci-dessous

CREATE FUNCTION [dbo].[udfSoundex] 
(
    @Soundex nvarchar(100) 
) 
RETURNS nvarchar(100) 
AS 
BEGIN 
    RETURN Soundex(@Soundex) 
END 

faites-la glisser depuis l'Explorateur de serveur sur vous contexte de données dans le fichier dbml studio visuel et l'utiliser dans le code comme méthode exposée sur votre classe DataContext ..

4

Depuis .net 4 cette fonctionnera aussi:

from p in mytable 
where SqlFunctions.SoundCode(p.MyRow) == SqlFunctions.SoundCode("test") 
select p 

Plus d'infos ici: http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.soundcode.aspx

+1

Cela semble être une référence à Entity Framework et PAS Linq à SQL qui explique pourquoi il n'y a pas up-votes. – jpierson

+0

@jpierson Vrai, mon mauvais. Mais j'ai trouvé cette question à la recherche d'une solution EF, alors peut-être que cela aidera quelqu'un. – Marthijn

0

Vous pouvez également utiliser la méthode SqlFucntions.Difference, qui associe à la fonction Soundex:

SqlFunctions.Difference (string, string) int - plus la valeur de retour, plus « similaires » les chaînes sont.

+0

Ceci est EF, pas Linq To SQL. –