web-dev-qa-db-fra.com

Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte

J'ai vu beaucoup de questions sur ce sujet, mais je n'ai pas pu trier aucune d'entre elles qui résout réellement le problème que je vois. J'ai une entité d'activités qui suit à quel employé il est affecté ainsi qu'à quel employé a créé l'enregistrement et l'a mis à jour. Si je supprime la ligne de code `where a.AssignedEmployee == currentUser ', je ne reçois pas l'erreur d'exécution ci-dessous.

Impossible de créer une valeur constante de type "DataModels.Employee". Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte.

MANETTE

var query = from a in db.Activities
            where a.AssignedEmployee == currentUser
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());

VUE

@model IEnumerable<Data.DataModels.Activity>
..........
37
RSolberg

Je suppose que cette erreur indique que EF ne peut pas traduire l'opérateur d'égalité pour Employee en SQL (que vous supposiez l'égalité référentielle ou un opérateur == Substitué). En supposant que la classe Employee a un identifiant unique, essayez:

var query = from a in db.Activities
            where a.AssignedEmployeeId == currentUser.Id
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());
63
D Stanley

Il n'aime pas le fait que vous essayez de convertir une égalité d'objet entier en une requête de base de données. Vous ne pouvez effectuer des requêtes de structure d'entité qu'en utilisant des valeurs constantes, un peu comme vous le feriez pour des requêtes SQL. La façon de résoudre ce problème serait de comparer les ID pour voir si l'ID de l'assigné de l'employé est le même que l'ID de l'utilisateur actuel dans la table des employés.

En guise de remarque, si l'objet currentUser que vous suivez n'est pas du type Employé, vous pouvez envisager de mettre en cache l'enregistrement Employé correspondant de cet utilisateur pour mieux pouvoir le référencer dans des requêtes ultérieures. Ce serait beaucoup mieux que d'essayer de parcourir ce tableau constamment. (Encore une fois, cela ne vous affecterait que si c'est en fait dans un autre tableau)

7
IronMan84

Le problème avec l'utilisation de == et obj.Equals est qu'Entity Framework ne sait pas comment traduire cet appel de méthode en SQL --- même si vous surchargez ces deux méthodes en quelque chose qui se traduirait en SQL. Ce que vous pouvez faire pour corriger cette lacune dans Entity Framework est de créer une méthode qui renvoie un arbre d'expression qui effectue la vérification d'égalité la plus complexe que vous souhaitez effectuer.

Par exemple, disons que nous avons la classe suivante

public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}

Afin de renvoyer une opération d'égalité personnalisée que Entity Framework peut comprendre, ajoutez la méthode suivante à la classe Person:

public static Expression<Func<Person, bool>> EqualsExpressionTree(  Person rhs )
{
    return ( lhs ) => string.Equals( lhs.Firstname, rhs.Firstname ) &&
                      string.Equals( lhs.Lastname, rhs.Lastname );
}

Dans vos requêtes LINQ, vous pouvez tirer parti de votre code d'égalité personnalisé comme suit:

Person anotherPerson = new Person { Firstname = "John", Lastname = "Doe" }
personCont.Where( Person.EqualsExpressionTree(anotherPerson) );
//...
if ( personCont.Any( Person.EqualsExpressionTree(anotherPerson)) ) {
//...

En outre, la méthode EqualsExpressionTree peut être réécrite pour appeler une méthode statique Equals, vous permettant de tirer parti de votre logique d'égalité personnalisée. Cependant, n'oubliez pas que votre code doit se traduire par une expression SQL, car nous appelons après tout à une base de données et n'accédons pas à des éléments de la mémoire.

4
rmiesen