2016-08-09 67 views
0

Ich bekomme den folgenden Fehler, aber ich bin nicht sicher, wie ich meine Aussage umschreiben? Irgendwelche Ideen?Entity Framework - Zeichenfolge Konvertierung Fehler

Fehler:

LINQ to Entities does not recognize the method 'System.String Convert(System.String)' method, and this method cannot be translated into a store expression

Code:

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
      && ((Convert(c.TelephoneHome) == mobile) || (Convert(c.TelephoneMobile) == mobile) || (Convert(c.TelephoneWork) == mobile))); 
    return client; 
} 

public static string Convert(string mobile) 
{ 
    var filterNumber = from letter in mobile 
         where char.IsDigit(letter) 
         select letter; 

    StringBuilder number = new StringBuilder(); 
    number.Append(filterNumber.ToArray()); 

    return number.ToString(); 
} 
+2

Der Fehler bedeutet, dass Linq Ihren Ausdruck in eine Sql-Anweisung übersetzen muss. Ihre benutzerdefinierte 'Convert'-Methode ist nicht übersetzbar, da es sich um C# -Code handelt und nicht um etwas, das auch auf dem Datenbankserver existiert. – Igor

+0

Hallo, danke, aber ich habe das Problem bereits erwähnt, ich fragte, aber ich bin nicht sicher, wie ich meine Aussage umschreiben soll? –

+0

Telefonnummer ist in einer Zeichenfolge –

Antwort

4

Der Fehler bedeutet, dass Linq Ihren Ausdruck in eine SQL-Anweisung übersetzen muss. Ihre benutzerdefinierte Konvertierungsmethode ist nicht übersetzbar, da es sich um C# -Code handelt und nicht um etwas, das auch auf dem Datenbankserver vorhanden ist.

Da Sie Ihre Kontonummer bereits übergeben, gehe ich davon aus, dass dies entweder eindeutig ist ODER Sie filtert sie so weit herunter, dass sie nahezu eindeutig ist, um sicherzustellen, dass Sie eine große Anzahl von Objekten nicht abrufen. Sie können dann das Objektdiagramm zuerst materialisieren und dann mehr in C# (linq to objects) filtern. Dies geschieht mit dem Aufruf ToList().

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    var clients = RepositorySet.Include("Account").Where(c => c.AccountId == accountId && !c.IsDeleted).ToList(); 
    return clients.FirstOrDefault(client => Convert(client.TelephoneHome) == mobile || Convert(client.TelephoneMobile) == mobile || Convert(client.TelephoneWork) == mobile); 
} 
+0

Das ist ziemlich schlau. Gute Stelle! –

1

Ist dies zu Ihnen passt, wie Sie in Ihrem Kommentar erwähnt

@Imad, what im trying to do is validate, so if the number has been stored in the database as 0331-9000-100, I want to remove all non numeric characters, mobile has already had this applied, so mobile = 033319000100

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
      && ((c.TelephoneHome.Replace("-","") == mobile) || (Convert(c.TelephoneMobile) == mobile) || (Convert(c.TelephoneWork) == mobile))); 
    return client; 
} 

Replace mit Ihnen auch andere Charaktere wie ( und ) auch ersetzen können.

Punkt zu erinnern: Replace(char, char) wird nicht funktionieren, aber Replace(string, string) wird.

0

Das erste Problem ist, dass der Convert-Aufruf ein C# ist und nicht in SQL übersetzt werden kann. Nicht alle Funktionen können, aber einige (z. B. Teilstrings) sind dem Entity Framework "bekannt" und können sie in das entsprechende SQL konvertieren. Sie müssen also entweder Ihre Anweisung neu schreiben, um die Zeichenfolgenfunktionen zu verwenden, die EF kennt, oder die Logik auf andere Weise in die Datenbank verschieben.

@Imad hat bereits vorgeschlagen, string.Replace mit, die EF bekannt ist, aber natürlich geht es nicht, dass Sie alle möglichen Nicht-Ziffernzeichen entfernen helfen - nur diejenigen, die Sie explizit für codieren, wie ‚-‘, aber keine anderen Alpha-Strings wie 'extension'.

Wenn Sie das schnell machen möchten, ist es vielleicht eine gute Idee, die 'bereinigten' Nummern in separaten Feldern zu speichern. Dann wird die Abfrage

Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
     && (c.TelephoneHomeClean == mobile) || (c.TelephoneMobileClean == mobile) || (c.TelephoneWorkClean == mobile))); 
return client; 

und Sie haben etwas, das viel schneller und indiziert werden kann.

+0

gute Idee für die langfristige, wie ich einige SP schreiben müssen, um die Daten zu prüfen/zu aktualisieren. –

+0

Ja, es ist definitiv ärgerlicher Aufwand, als du vielleicht willst. –