Entity Framework / Linq EXpression konvertiert von String in int

Ich habe einen Ausdruck wie folgt:

var values = Enumerable.Range(1,2); return message => message.Properties.Any( p => p.Key == name && int.Parse(p.Value) >= values[0] && int.Parse(p.Value) <= values[1]); 

Dies kompiliert, aber wenn es die database trifft, wirft es die Ausnahme 'LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression '

Wenn ich die Analyse nicht mache und Werte eine string[] habe, kann ich dann die Operatoren >= und <= für Zeichenfolgen nicht verwenden.

p.Value ist eine Zeichenkette, die verschiedene Werte enthält, aber in diesem Fall ist es int

Gibt es eine Möglichkeit, die database abzufragen, um diese Art von Aussage zu machen?

Wie von anderen in den Kommentaren erwähnt, sollte die Tatsache, dass Sie diesen Wert analysieren müssen, eine rote Markierung sein, dass Sie einen anderen Datentyp in Ihrer database verwenden sollten.

Glücklicherweise gibt es eine Problemumgehung, indem die Abfrage von LINQ to Objects und nicht von LINQ to Entities ausgeführt wird. Unglücklicherweise bedeutet dies, dass möglicherweise eine große Menge an Daten in den Speicher gelesen wird

BEARBEITEN

Aufgrund Ihrer anderen Kommentare ist der Wert in der Spalte Wert nicht garantiert eine Zahl. Daher müssen Sie versuchen, den Wert in eine Zahl zu konvertieren und dann basierend auf dem Fehler / Erfolg der Konvertierung zu handeln:

 return message .Properties .AsEnumerable() .Any(p => { var val = 0; if(int.TryParse(p.Value, out val)) { return p.Key == name && val >= values[0] && val < = values[1]) } else { return false; } ); 

BEARBEITEN 2

Sie könnten tatsächlich damit in der database durchkommen. Ich bin mir nicht sicher, ob das für Sie funktioniert oder nicht, aber versuchen Sie es:

 return message.Properties .Where(p => p.Key == name && SqlFunctions.IsNumeric(p.Value) > 0) .Any(p => Convert.ToInt32(p.Value) >= values[0] && Convert.ToInt32(p.Value) < = values[1]); 

So sehr ich diese Antwort hasse. Die tatsächliche Antwort ist, dass Sie es nicht leicht tun können. Es wird ein echter Schmerz sein. Ich habe viele falsche Antworten und viele Antworten mit Leuten gesehen, die sagten, dass Sie Ihre databasefelder einfach von vornherein richtig formatieren sollten. nicht hilfreich.

Diese Frage ähnelt http://social.msdn.microsoft.com/Forums/en-US/ce9652e3-5450-44c4-a9bd-586b4c4e6a27/convert-string-to-int-in-whereorderby-is-it-possible ? Forum = Adodottentitätsrahmen

Je nachdem, welche Art von EF Sie verwenden, gibt es verschiedene Möglichkeiten.

1. Sie verwenden EDMX-Dateien.

(Erst Code oder Reverse Engineering Code nicht zuerst codieren). Sie können etwas wie verwenden ( LINQ to Entities erkennt die Methode ‘Double Parse (System.String)’ nicht und diese Methode kann nicht in einen Ausdruck übersetzt werden )

  [EdmFunction("PlusDomain", "ParseDouble")] public static double ParseDouble(string stringvalue) { /// This method exists for use in LINQ queries, /// as a stub that will be converted to a SQL CAST statement. return System.Double.Parse(stringvalue); } 

und mappe in deinem EDMX

 >  >  >  > cast(stringvalue as Edm.Double) >  >  

2. Wenn Sie Code zuerst in EF> = 4.1 verwenden.

Du bist geschraubt. Microsoft hielt es nicht für sinnvoll, SqlFunctions eine solche function hinzuzufügen. Das Beste, auf das Sie hoffen können, ist das Hinzufügen einer skalaren SQL-function in Ihre database und (möglicherweise) versuchen Sie es in Ihren Kontext zu mappen. Microsoft hat keinen Sinn darin gesehen, zuerst so etwas in Code zu machen. Zum Glück haben sie solche Dinge auch nicht völlig blockiert. Die Fluent API ist leistungsstark.

Es wird ungefähr so ​​sein:

Sie können die functionen oder gespeicherten Prozeduren wie folgt aufrufen : Definieren Sie zuerst die Skalarfunktion mit ef4.1-Code? oder http://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-hat-output-parameters wie:

var outParam = neuer SqlParameter (“overHours”, SqlDbType.Int); outParam.Direction = ParameterDirection.Output;

var data = context.Database.ExecuteSqlCommand (“dbo.sp_getNumberJobs @ overHours OUT”, outParam); int numJobs = (int) outParam.Value;

Um sie jedoch in LinQ in Entitäten zu integrieren, benötigen Sie etwas mehr:

https://codefirstfunctions.codeplex.com/ unter Verwendung von http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions ordnet es die SQL-functionen in den Kontext ein, verwendet jedoch eine externe Bibliothek, die nur für .NET 4.5 erstellt wurde http: // blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/

oder Sie können versuchen, dasselbe manuell mit etwas zu tun wie:

Entity Framework 6 Code Erste functionszuordnung oder

https://entityframework.codeplex.com/discussions/494365

oder die schnellere Lösung, die ich für meine Bedürfnisse eingerichtet habe, ist einfach eine Ansicht mit den konvertierten Typen zu erstellen. Dies vermeidet das ganze Problem.

Kürzlich musste ich eine Zeichenfolge (numerische Darstellung) in einen Enumerationswert in einer LINQ-Abfrage konvertieren, ohne die Abfrage zu materialisieren. Meine Enumeration verwendete int Werte zwischen 0 und 9, also habe ich so etwas gemacht:

  .Select(str => (MyEnum?)(SqlFunctions.Unicode(str) - 48)) 

Ich weiß, dass dies keine vollständige Lösung für das Problem bietet, aber es funktioniert definitiv in einer Situation wie meiner. Vielleicht finden manche es nützlich.

Sie können Convert.ToInt32(input); versuchen Convert.ToInt32(input); Wenn Sie nicht sicher sind, können Sie TryParse . Es wird keine Ausnahme auslösen, aber false kann nicht parsen. Aber Convert.ToInt32(input); sollte arbeiten. Sie können darüber auf http://msdn.microsoft.com/en-us/library/vstudio/bb397679.aspx nachlesen.