2010-04-21 18 views
11

ich den folgenden Code verwenden:Concatenate int und String in LINQ to Entities

from c in Country 
where c.IsActive.Equals(true) 
orderby c.CountryName 
select new 
{ 
    countryIDCode = c.CountryID + "|" + c.TwoDigitCode, 
    countryName = c.CountryName 
} 

Aber ich habe diesen Fehler, während es ausgeführt wird:

Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.

CountryID ist int Art und TwoDigitCode ist string Typ .

Wie verkette ich richtig?

Antwort

6

Wenn dieser Fehler Sie das Fortschreiten verhindert und ist eine kleine Datenmenge können Sie Ihre Abfrage aus der Datenbank von durch Aufzählen der Abfrage (Call Hydrat könnten Auflisten). Ab diesem Zeitpunkt sind Ihre Operationen gegen In-Memory-Objekte gerichtet, und Sie können möglicherweise nicht auf den Fehler stoßen, den Sie erhalten.

var countries = (from c in Country 
where c.IsActive.Equals(true) 
orderby c.CountryName 
select c).ToList(); 


var countryCodes = (from c in countries 
where c.IsActive.Equals(true) 
    orderby c.CountryName 
    select new 
    { 
     countryIDCode = c.CountryID + "|" + c.TwoDigitCode, 
     countryName = c.CountryName 
    }); 
+6

Ich denke, diese Antwort ist veraltet und insgesamt schlechte Praxis. Es ist ein Quick'n'Dirty-Fix, der für den Moment funktioniert, aber Sie später beißen wird (z. B. wenn Ihr momentan kleiner Datensatz plötzlich wächst, oder der Kunde entscheidet, dass er dasselbe auf einem anderen, viel größeren Datensatz möchte). Sehen Sie sich die Antwort von flyfisher1952 an, die db-Funktionen direkt verwendet, wodurch es das Problem viel besser löst als diese Antwort. – Mtz

-3

Verwenden c.CountryId.ToString() eine String-Darstellung Ihrer CountryId zu bekommen und das Feld zu Ihrem TwoDigitCode verketten:

from c in Country 
where c.IsActive.Equals(true) 
orderby c.CountryName 
select new 
{ 
    countryIDCode = c.CountryID.ToString() + "|" + c.TwoDigitCode, 
    countryName = c.CountryName 
} 

ich Ihre Störungshoffnungproenergie ist eigentlich ein Compiler-Fehler (kann nicht von irgendeiner Weise denken, der Compiler ermöglicht, Ich bin mir nicht sicher, wie es über den Linq to Entities-Teil bekannt ist.

+2

Nein, dies kann nicht verwendet werden. Folgefehler in diesem Fall: LINQ to Entities erkennt die Methode 'System.String ToString()' nicht, und diese Methode kann nicht in einen Speicherausdruck übersetzt werden. – Waheed

+0

ist das eine Ausnahme oder ein Compilerfehler? –

+0

Es gibt Laufzeitfehler. Versucht, wie Sie sagten :( – Waheed

-3

Wenn Sie brauchen, um sie verketten zusammen als String könnte man String.Format Methode verwenden:

countryIDCode = String.Format("{0}|{1}", c.CountryID, c.TwoDigitCode) 
+1

Nein gibt es Laufzeitfehler: LINQ to Entities erkennt die Methode 'System.String Format (System.String, System.Object, System .Object) 'Methode, und diese Methode kann nicht in einen Ausdruck übersetzt werden – Waheed

+1

.ToString() und .Format() kann nicht auf dem SQL-Client ausgeführt werden, so dass dies einen Laufzeitfehler geben wird. – gingerbreadboy

+3

Nun, die Frage war 'Concatenate int und string in LINQ' nicht in Linq To SQL usw. Das OP hätte klarer sein müssen LINQ! = SQL –

5

dieses Thema eine Liste der CLR Methoden enthält, die konvertiert werden können Baum kanonische Funktionen und ausgeführt auf dem Server zu befehlen:

MSDN

Für CLR Verfahren nicht in dieser Liste, würden Sie die Ergebnisse bis auf den Client mit .AsEnumerable ziehen müssen() und eine LINQ to Objects-Abfrage auszuführen.

2

Dies ist eine Einschränkung der alten Version des Entity Framework. Ich denke, dass mit v4 ist es gelöst. Für Ihre Version ist die Abhilfe das Ergebnis in einem zählbaren zu konvertieren:

from a in 
(from c in Country 
where c.IsActive.Equals(true) 
orderby c.CountryName).AsEnumerable() 
select new 
{ 
    countryIDCode = a.CountryID + "|" + a.TwoDigitCode, 
    countryName = a.CountryName 
} 
+0

Ich versuche Ihre Methode, aber ich bekomme Kompilierzeit Fehler: Ein Abfragekörper muss mit einer SELECT-Klausel enden oder eine Gruppenklausel. – Waheed

+0

Entschuldigung, es gab einen Syntaxfehler ... Ich habe es bearbeitet, versuche es jetzt. –

+0

Die Abfrage, die Sie anzeigen, funktioniert mehr oder weniger korrekt in EF 1 und 4. –

2

Es gibt keine mapping to a Canonical Function für die int String Casting.

zurückkehren So einfach Int und die String in 2 verschiedenen Spalten und sie dann nach der Verwendung der AsEnumerable Methode in .NET verketten:

var cListTemp = from c in Country 
    where c.IsActive.Equals(true) 
    orderby c.CountryName 
    select new 
    { 
     countryID = c.CountryID, 
     twoDigitCode = c.TwoDigitCode, 
     countryName = c.CountryName 
    }; 

var cList = cListTemp.AsEnumerable().Select(c => new { 
    countryIDCode = c.countryID + "|" + c.twoDigitCode, 
    countryName = c.countryName 
}); 
22

Verwenden System.Data.Objects.SqlClient .SqlFunktionen.StringConvert

from c in Country 
where c.IsActive.Equals(true) 
orderby c.CountryName 
select new 
{ 
    countryIDCode = SqlFunctions.StringConvert((double)c.CountryID) 
        + "|" + c.TwoDigitCode, 
    countryName = c.CountryName 
} 
+0

Hier, warum .ToString() oder Convert.ToString() Methoden nicht funktionieren? – shamim

+0

Ich bin mir nicht wirklich sicher. Die Datenbanktypen haben sich aus meiner Sicht immer etwas merkwürdig verhalten, und SqlFunctions-Dienstprogramme sind das, was ich verwendet habe, um Probleme wie die, die gepostet wurden, zu lösen. Ich favorisiere diesen Ansatz gegenüber weniger offensichtlichen Lösungen wie der ToList-Konvertierung, da ** explizit ** angezeigt wird, was Sie mit jedem tun, der Ihren Code beibehält. – flyfisher1952

+0

Ich glaube, dies sollte die akzeptierte Antwort sein, da es das Problem löst, ohne Performance-Strafen wie die Antwort von Nicholas Murray einzuführen (obwohl es sagt "... und ist ein kleiner Datensatz"). – Mtz

2

konnte ich Strings mit dem folgenden Code verketten:

l.StateName + " " + SqlFunctions.StringConvert((double?)l.Zip).Trim() 

Es scheint wie nur SqlFunctions.StringConvert((double?)l.Zip) gut genug sein würde, aber der resultierende String hat eine Reihe von Polsterung auf der linken Seite, die bewirkt, dass Zeichenfolgenvergleiche nicht übereinstimmen. Stellt sich heraus, Trim() funktioniert, um das Extra zu rasieren. Ich glaube, SqlFunctions.StringConvert((double?)l.Zip).Trim() wird effektiv in die SQL: LTrim(RTrim(STR(Zip))).