He pasado los últimos 6 meses luchando contra esta limitación con EF 3.5 y, aunque no soy la persona más inteligente del mundo, estoy bastante seguro de que tengo algo útil que ofrecer sobre este tema.
El SQL generado por el crecimiento de un árbol de 50 millas de alto de expresiones de "estilo OR" dará como resultado un plan de ejecución de consulta deficiente. Estoy tratando con unos pocos millones de filas y el impacto es sustancial.
Hay un pequeño truco que encontré para hacer un SQL 'en' que ayuda si solo está buscando un montón de entidades por id:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
donde pkIDColumn es el nombre de la columna de identificación de la clave principal de su tabla Entity1.
¡PERO SIGUE LEYENDO!
Esto está bien, pero requiere que ya tenga los identificadores de lo que necesito encontrar. A veces solo quiero que mis expresiones lleguen a otras relaciones y lo que sí tengo son criterios para esas relaciones conectadas.
Si tuviera más tiempo, trataría de representar esto visualmente, pero no me limito a estudiar esta oración un momento: considere un esquema con tablas Person, GovernmentId y GovernmentIdType. Andrew Tappert (Person) tiene dos tarjetas de identificación (GovernmentId), una de Oregon (GovernmentIdType) y otra de Washington (GovernmentIdType).
Ahora genere un edmx a partir de él.
Ahora imagine que desea encontrar a todas las personas que tengan un determinado valor de ID, digamos 1234567.
Esto se puede lograr con un solo acceso a la base de datos con esto:
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
¿Ves la subconsulta aquí? El sql generado usará 'uniones' en lugar de subconsultas, pero el efecto es el mismo. En estos días, el servidor SQL optimiza las subconsultas en combinaciones bajo las cubiertas de todos modos, pero de todos modos ...
La clave para este trabajo es el .Any dentro de la expresión.