Pregunta

Tengo una consulta Linq to Entities como esta:

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == (int)pCategory
              select r;

Por lo general, utilizo el siguiente código para verificar si se devuelven algunos resultados:

if (results.Count() > 0)
{
    return new oMachineRevision(results.First().IdMachineRevision);
}

Sin embargo, obtengo NotSupportedException en la condición if .

El mensaje de error es: No se puede crear un valor constante de tipo 'Tipo de cierre'. Solo los tipos primitivos ('como Int32, String y Guid') son compatibles en este contexto.

Tenga en cuenta que pCategory es un tipo Enum.

¿Fue útil?

Solución

EDITAR : según su actualización, el error puede estar relacionado con una enumeración en su clase de entidad. Consulte esta entrada de blog para obtener más información y un trabajo -alrededor. Dejo mi respuesta original como una mejora en la sintaxis de su consulta.

Intente seleccionar la primera entidad en la consulta usando FirstOrDefault y luego verifique si el resultado es nulo.

int compareCategory = (int)pCategory; // just a guess
var result = (from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == compareCategory
              select r).FirstOrDefault();

if (result != null)
{
     return new oMachineRevision(result.IdMachineRevision);
}

Otros consejos

¿Por qué no usar FirstOrDefault () en su lugar y verificar nulo? No puedo ver el beneficio de consultar el recuento y luego tomar el primer elemento.

En la implementación estándar de linq, los operadores " seleccione " y " donde " mapear a métodos que devuelven un IEnumerable o IQueryable. Entonces, los métodos linq estándar cuando se usan siempre deben devolver un IEnumerable de su consulta, no un solo objeto.

Pero los métodos linq que son candidatos para los operadores linq no están restringidos a los métodos que devuelven IEnumerables, se puede elegir cualquier método que devuelva cualquier cosa.

En caso de que tenga métodos de instancia llamados " Seleccione " y " Donde " que devuelven un único objeto o métodos de extensiones que son específicos de su clase y devuelven un único objeto, que se utilizarán en lugar de los linq estándar.

Mi suposición es que, o bien " Seleccione " o " Donde " El método definido en su clase es hacer que linq devuelva un valor único en lugar de un IEnumerable<T>.

No sabía que se crearían diferentes objetos anónimos dependiendo del resultado de la consulta. Supongo que solo querían que los resultados fueran del tipo IEnumerable

¿Qué tal usar un foreach?

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == pCategory
              select r;

foreach( var r in results )
{
    yield return new oMachineRevision( r.IdMachineRevision );
}

Esto también se aplica a todos los tipos implícitos. Debo admitir que sigo olvidando esto y así es como me encontré con esta publicación.

si tienes

class ClassA {
               ...

               private string value;

               ...

               public static implicit operator string(ClassA value)
               {
                    return value.ToString();
               } 

              ...
}

necesitas lanzar explícitamente la clase a astring para comparar.

así que generalmente hago esto

    var myClassAStr = myClassA.ToString();

    var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();

// do stuff with x
    ...

intente usar

IENumerable<MachineRevision> results = from r in entities.MachineRevision
...

en su lugar.

Creo que es la var la que está causando el problema.

Editar:

Lea el mensaje de error. " No se puede crear un valor constante de tipo 'Tipo de cierre'. Solo los tipos primitivos ('como Int32, String y Guid') son compatibles en este contexto. & Quot;

Una de estas comparaciones es con un tipo que no es int, string o guid. Supongo que la categoría.

r.Machine.IdMachine == pIdMachine && r.Category == pCategory

Curiosamente, LinqToSql permitirá esta construcción. No sé por qué LinqToEntities no es compatible con esto.

Creo que también podría seleccionar el elemento que desea de otra manera más simple mediante el uso de expresiones lambda.

var result = entities.MachineRevision
                 .Where(x => x.Machine.IdMachine == pIdMachine)
                 .Where(y => y.Category == (int)pCategory)
                 .FirstOrDefault();

if (result != null)
{
     return new oMachineRevision(result.IdMachineRevision);
}

y luego proceder como lo haría normalmente

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top