2009-02-23 26 views
25

Tengo problemas para hacer que LINQ traduzca algo en la consulta que necesito. En T-SQL, hacemos una comparación < = y> = en tres columnas que son columnas CHAR (6). LINQ no permitirá que lo haga desdeProblemas al hacer una comparación de cadenas en LINQ

operador < = 'no se puede aplicar a operandos de tipo 'cadena' a 'cadena'.

que tienen la siguiente consulta T-SQL ..

SELECT * 
FROM [ZIPMASTER] zm 
WHERE zm.CORP = 12 
AND '85546 ' BETWEEN zm.ZIPBEG AND zm.ZIPEND 

Lo anterior no es muy simpático LINQ, ya que no hay soporte para BETWEEN. Por lo tanto, he simplificado a lo siguiente:

SELECT * 
FROM [ZIPMASTER] zm 
WHERE zm.CORP = 12 
AND zm.ZIPBEG <= '85546 ' 
AND zm.ZIPEND >= '85546 ' 

que he usado para crear la siguiente consulta LINQ:

var zipLinqQuery = 
    from z in db.ZIPMASTERs 
    where z.CORP == 12 
    && z.ZIPBEG <= "85546 " 
    && z.ZIPEND >= "85546 " 
    select z; 
List<ZIPMASTER> zips = zipLinqQuery.ToList<ZIPMASTER>(); 

C# - LINQ no es gusto esta consulta demasiado. Traté de convertir a Ints y luego comparar, sin embargo, en algunos casos, el código postal puede contener una letra. Por ejemplo, la siguiente expresión evaluaría como verdadero en T-SQL:

WHERE '85546B' BETWEEN '85546A' AND '85546D' 

No sé exactamente por qué funciona en T-SQL, pero mi conjetura es que compara cada personaje de la serie individualmente convirtiéndolo en un valor numérico ASCII.

De todos modos, cualquier ayuda que puedan brindar es muy apreciada. Gracias por adelantado.

CJAM

Solución (publicado por Jon Skeet):

Parece que string.CompareTo() lo hace, de hecho, es necesario generar el T-SQL. Ejemplos a continuación:

var zipLinqQuery = 
    from z in db.ZIPMASTERs 
    where z.CORP == listItem.CORP 
    && z.ZIPBEG.CompareTo(listItem.ZIPCODE) <= 0 
    && z.ZIPEND.CompareTo(listItem.ZIPCODE) >= 0 
    select z; 

genera la siguiente T-SQL:

DECLARE @p0 INT, @p1 CHAR(6), @p2 CHAR(6) 
SET @p0 = 12 
SET @p1 = '85546 ' 
SET @p2 = '85546 ' 

SELECT [t0].[CORP], [t0].[ZIPEND], [t0].[ZIPBEG], [t0].[CITY], [t0].[STATE], [t0].[CYCLE] 
FROM [dbo].[ZIPMASTER] AS [t0] 
WHERE ([t0].[CORP] = @p0) AND ([t0].[ZIPBEG] <= @p1) AND ([t0].[ZIPEND] >= @p2) 

Respuesta

39

Probar:

var zipLinqQuery = 
    from z in db.ZIPMASTERs 
    where z.CORP == 12 
    && z.ZIPBEG.CompareTo("85546 ") <= 0 
    && z.ZIPEND.CompareTo("85546 ") >= 0 
    select z; 

No sé que String.CompareTo trabaja en LINQ a SQL, pero es lo primero que debes intentar

(Normalmente, debe utilizar un StringComparer para especificar el tipo de comparación, pero sospecho que en este caso CompareTo es la mejor opción.)

+0

Esto funciona, pero de ninguna manera para hacer un método de extensión de uso general de ¿eso? Jugué un poco pero no pude encontrar nada que L2S pudiera traducir. Hice trabajo para IEnumerables. – andleer