¿Por qué recibo el error?
No se puede crear un valor constante de tipo 'Tipo de cierre'. En este contexto, solo se admiten los tipos primitivos (por ejemplo, Int32, String y Guid).
¿Cuando intento enumerar la siguiente consulta de Linq?
IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
var myList = from person in entities.vSearchPeople
where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}
Actualización : si intento lo siguiente solo para tratar de aislar el problema, aparece el mismo error:
where upperSearchList.All(arg => arg == arg)
Entonces, parece que el problema está en el método All, ¿verdad? ¿Alguna sugerencia?
fuente
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.
fuente
Encontré la causa del error (estoy usando Framework 4.5). El problema es que EF, un tipo complejo, que se pasa en el parámetro "Contiene", no se puede traducir a una consulta SQL. EF puede usar en una consulta SQL solo tipos simples como int, string ...
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll proporciona una lista de objetos con un tipo complejo (por ejemplo: "Función"). Por lo tanto, aquí intentaría recibir una instancia de este tipo complejo en mi consulta SQL, ¡que naturalmente no puede funcionar!
Si puedo extraer de mi lista los parámetros que se adapten a mi búsqueda, puedo usar:
var idList = assignedFunctions.Select(f => f.FunctionId); this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Ahora EF ya no tiene el tipo complejo "Función" para trabajar, sino, por ejemplo, con un tipo simple (largo). ¡Y eso funciona bien!
fuente
Recibí este mensaje de error cuando mi objeto de matriz utilizado en la función .All es nulo Después de inicializar el objeto de matriz (upperSearchList en su caso), el error desapareció El mensaje de error fue engañoso en este caso
donde upperSearchList.All (arg => persona.algunospropiedades.StartsWith (arg)))
fuente