Question

J'ai une requête Linq to Entities comme celle-ci:

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

D'habitude, j'utilise le code ci-dessous pour vérifier si des résultats sont renvoyés:

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

Toutefois, NotSupportedException apparaît dans la condition si .

Le message d'erreur est le suivant: Impossible de créer une valeur constante de type 'Type de fermeture'. Seuls les types primitifs ('tels que Int32, String et Guid') sont pris en charge dans ce contexte.

Notez que pCategory est un type Enum.

Était-ce utile?

La solution

MODIFIER : selon votre mise à jour, l'erreur peut être liée à une énumération de votre classe d'entité. Voir cette entrée de blog pour plus d'informations et un travail. -autour. Je laisse ma réponse initiale comme une amélioration de la syntaxe de votre requête.

Essayez de sélectionner FirstOrDefault en sélectionnant la première entité dans la requête, puis vérifiez si le résultat est null.

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);
}

Autres conseils

Pourquoi ne pas simplement utiliser FirstOrDefault () à la place et rechercher la valeur null? Je ne vois pas l'intérêt de demander le nombre, puis de prendre le premier élément.

Dans l'implémentation standard de linq, les opérateurs " sélectionnent " et " où " mapper vers des méthodes qui renvoient un IEnumerable ou IQueryable. Les méthodes linq standard utilisées doivent donc toujours renvoyer un IEnumerable à partir de votre requête et non un seul objet.

Mais les méthodes linq candidates aux opérateurs linq ne sont pas limitées aux méthodes renvoyant IEnumerables, vous pouvez choisir n'importe quelle méthode renvoyant n'importe quoi.

Si vous avez des méthodes d'instance nommées " sélectionnez " et " Où " qui renvoient un seul objet ou des méthodes d'extensions spécifiques à votre classe et renvoient un seul objet, celles-ci seront utilisées à la place de celles de linq standard.

Je suppose que c'est soit un & "Sélectionnez &"; ou " Où " La méthode définie dans votre classe fait que linq retourne une valeur unique au lieu d’un IEnumerable<T>.

Je ne savais pas que différents objets anonymes seraient créés en fonction du résultat de la requête. Je suppose qu'ils voulaient juste que les résultats soient de type IEnumerable

Pourquoi ne pas utiliser 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 );
}

Cela vaut également pour tous les types implicites. Je dois avouer que je ne cesse d’oublier cela et c’est comme cela que j’ai découvert ce message.

si vous avez

class ClassA {
               ...

               private string value;

               ...

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

              ...
}

vous devez explicitement diriger la classe vers astring pour la comparer.

alors je le fais habituellement

    var myClassAStr = myClassA.ToString();

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

// do stuff with x
    ...

essayez d'utiliser

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

à la place.

Je pense que son var est la cause de votre problème.

Modifier:

Lisez le message d'erreur. & "; Impossible de créer une valeur constante de type" Type de fermeture ". Seuls les types primitifs ('tels que Int32, String et Guid') sont pris en charge dans ce contexte. & Quot;

L’une de ces comparaisons est avec un type qui n’est pas int, chaîne ou guid. Je devine la catégorie.

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

Fait intéressant, LinqToSql autorisera cette construction. Je ne sais pas pourquoi LinqToEntities ne le supporte pas.

Je pense que vous pouvez également sélectionner l'élément de votre choix d'une manière plus simple en utilisant des expressions 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);
}

et ensuite comme d'habitude

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top