Entity Framework / Linq EXpression conversione da stringa a int

Ho un’espressione in questo modo:

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]); 

Compila bene ma quando colpisce il database genera l’eccezione 'LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression '

Se non eseguo l’analisi e i valori sono una string[] non posso quindi utilizzare gli operatori >= e <= sulle stringhe.

p.Value è una stringa che contiene vari valori ma in questo caso è int

C’è un modo in cui posso interrogare il database per fare questo tipo di tra una dichiarazione?

Come sottolineato da altri nei commenti, il fatto che tu debba analizzare questo valore dovrebbe essere una bandiera rossa che dovresti usare un tipo di dati diverso nel tuo database.

Fortunatamente, esiste una soluzione alternativa forzando la query a essere eseguita da LINQ su oggetti anziché da LINQ a entity framework. Sfortunatamente, significa potenzialmente leggere una grande quantità di dati in memoria

MODIFICARE

Sulla base dei tuoi altri commenti, il valore nella colonna Valore non è garantito essere un numero. Pertanto, dovrai provare a convertire il valore in un numero e quindi a gestire le cose in base al fallimento / successo di tale conversione:

 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; } ); 

MODIFICA 2

Potresti riuscire a farla franca nel database. Non sono sicuro che questo funzionerà o meno per te, ma dagli una possibilità:

 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]); 

Per quanto odio questa risposta. La vera risposta è che non puoi farlo facilmente. Sarà un vero dolore. Ho visto molte risposte sbagliate e molte risposte con persone che dicono che dovresti semplicemente avere i campi del database come il tipo corretto in primo luogo. Non d’aiuto.

Questa domanda è simile a http://social.msdn.microsoft.com/Forums/en-US/ce9652e3-5450-44c4-a9bd-586b4c4e6a27/convert-string-to-int-in-whereorderby-is-it-possible ? forum = adodotnetentityframework

Ci sono diverse possibilità a seconda del tipo di EF che stai utilizzando.

1. Stai usando i file EDMX.

(Prima non codice o codice retroingegnerizzato). È ansible utilizzare qualcosa come ( LINQ to Entities non riconosce il metodo metodo ‘Double Parse (System.String)’ e questo metodo non può essere tradotto in un’espressione di archivio )

  [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); } 

e mappa nel tuo EDMX

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

2. Se si utilizza il codice per la prima volta in EF> = 4.1.

Sei fregato. Microsoft non ha ritenuto opportuno aggiungere alcuna funzione di questo tipo a SqlFunctions. Il meglio che puoi sperare è aggiungere una funzione SQL scalare al tuo database e (forse) provare a mapparla nel tuo contesto. Microsoft non ha visto alcun punto nel fare qualcosa di simile in codice prima. Fortunatamente non hanno bloccato totalmente neanche queste cose. L’API Fluent è potente.

Sarà qualcosa del genere:

È ansible chiamare le funzioni o le stored procedure come questa: definire prima la funzione scalare con il codice ef4.1? o http://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-hat-have-output-parameters come:

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

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

ma per farli realmente integrare in LinQ alle quadro hai bisogno di qualcosa di più simile a questo:

https://codefirstfunctions.codeplex.com/ utilizzando http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions associa le funzioni SQL nel contesto ma utilizza una libreria esterna creata per .NET 4.5 http: // blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/

oppure Puoi provare a fare la stessa cosa manualmente con qualcosa di simile:

Entity Framework 6 Code Prima mapping delle funzioni o

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

o la soluzione più rapida che ho risolto per le mie esigenze è semplicemente creare una vista con i tipi convertiti. Questo evita l’intero problema.

Recentemente ho dovuto convertire una stringa (rappresentazione numerica) in un valore di enumerazione in una query LINQ, senza materializzare la query. La mia enumerazione ha utilizzato valori int tra 0 e 9, quindi ho finito per fare qualcosa del genere:

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

So che questo non fornisce una soluzione completa per il problema, ma sicuramente funziona in una situazione come la mia. Forse alcuni lo troveranno utile.

Puoi provare Convert.ToInt32(input); Se non sei sicuro, puoi TryParse . Non genererà eccezioni, ma false non possono Parse. Ma Convert.ToInt32(input); dovrebbe funzionare. È ansible leggere su http://msdn.microsoft.com/en-us/library/vstudio/bb397679.aspx .