uso framework c# sql linq linq-to-entities like

c# - framework - linq a las entidades generadas sql



uso de like en linq c# (6)

Tengo algunos problemas con linq para las entidades en el marco de la entidad ado.net. Básicamente lo que estoy haciendo es esto:

var results = (from c in companies where c.Name.StartsWith(letter) select c);

y esto se traduce a SQL como algo así como:

WHERE (CAST(CHARINDEX(@p, [Extent1].[Name]) AS int)) = 1

lo cual está bien, pero mi tabla tiene millones de registros, por lo que esto funciona MUY lento. Lo que necesito para generar es algo así como:

DONDE Nombre LIKE @p + ''%''

Me buscaron alto y bajo y no puedo encontrar ninguna solución excepto para usar un procedimiento almacenado o usar la entidad sql ...

¿Hay alguna manera de hacer esto a través de linq? ¿Posiblemente al extender de algún modo el linq al proveedor de linq de entidades, o al interceptar de algún modo el árbol de comandos o la consulta generada?

¡Por favor ayuda!


¡Guau, esa es una forma realmente extraña de hacerlo! Tenga en cuenta que LINQ-to-SQL (en este caso) utiliza LIKE @p0 + ''%'' ... muy extraño.

¿Qué proveedor de EF (base de datos) estás usando? ¿Servidor SQL?

Como dices, un procedimiento almacenado será el trabajo, pero no deberías tener que hacer eso ... muy, muy extraño ...


No soy un experto en SQL pero supongo que ambas sintaxis:

DÓNDE (CAST (CHARINDEX (@p, [Extensión1]. [Nombre]) AS int)) = 1

y

DONDE Nombre LIKE @p + ''%''

dará como resultado una exploración de tabla o idealmente una exploración de índice. En pocas palabras, realizarán lo mismo. Lo verifiqué al ver los planes de ejecución a continuación. En pocas palabras, debe replantearse el esquema de la base de datos o la forma en que realiza su búsqueda. Este no es un problema LINQ.

Un área posible de mejora: asegúrese de haber indexado la columna en la que está buscando.

texto alternativo http://download.binaryocean.com/plan1.gif

texto alternativo http://download.binaryocean.com/plan2.gif


¿La "letra" es un char? Si hiciste una cadena, ¿qué sucede?

var results = (from c in companies where c.Name.StartsWith(letter.ToString()) select c);


Intenté usar esta sintaxis en su lugar

Name.Substring(0, 1) == "E"

Este SQL se genera

WHERE N''E'' = (SUBSTRING([Name], 0 + 1, 1))

Tal vez esto es más eficiente?


Este es un problema conocido con Linq to Entities. A diferencia de LIKE, aparentemente este constructo no usa índices.

Hemos tenido cierto éxito al usar Substring (que se traduce en SUBSTRING). El plan de ejecución es similar, pero en nuestro caso la consulta se ejecuta mucho más rápido.

Es otro "Estoy seguro de que se solucionará en EF 2" ... :-(


Puede usar un real como en Enlace a entidades con bastante facilidad

Esto es lo que se necesita para que funcione:

Añadir

<Function Name="String_Like" ReturnType="Edm.Boolean"> <Parameter Name="searchingIn" Type="Edm.String" /> <Parameter Name="lookingFor" Type="Edm.String" /> <DefiningExpression> searchingIn LIKE lookingFor </DefiningExpression> </Function>

a tu EDMX en esta etiqueta:

edmx: Edmx / edmx: Runtime / edmx: ConceptualModels / Schema

Recuerde también el espacio de nombres en el atributo <schema namespace="" />

A continuación, agregue una clase de extensión en el espacio de nombres anterior:

public static class Extensions { [EdmFunction("DocTrails3.Net.Database.Models", "String_Like")] public static Boolean Like(this String searchingIn, String lookingFor) { throw new Exception("Not implemented"); } }

Este método de extensión ahora se asignará a la función EDMX.

Más información aquí: http://jendaperl.blogspot.be/2011/02/like-in-linq-to-entities.html