L'entité ou de type complexe ... ne peuvent pas être construits en une requête LINQ to entities
Pourquoi une méthode de travail, mais pas de l'autre, quand il semble qu'ils sont tous les deux à faire la même chose, à savoir la construction d'une entité. Ma question alors, est-il un moyen de construire de l'entité dans une L2E requête au lieu d'utiliser la juste Linq ou même les deux?
Cela fonctionne bien...
var queryToList = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select new AuthorisationCheck
{
Blah = ac.Blah
}).ToList();
model.AuthorisationChecks = queryToList.Select(x => new AuthorisationCheck
{
Blah = x.Blah
}).ToList();
Cependant, si je change...
var queryToList
à
model.AuthorisationChecks queryToList //Of type List<AuthorisationCheck>
je reçois le message d'erreur dans le Titre...
The entity or complex type 'Model.AuthorisationCheck' cannot be constructed in a LINQ to Entities query.
EDIT:
Dans le modèle, il est tout simplement, rien de compliqué ici.
public List<AuthorisationCheck> AuthorisationChecks { get; set; }
EDIT2:
Rangé cela un petit peu (ce qui fonctionne très bien)...
model.AuthorisationChecks = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select ac).ToList()
.Select(x => new AuthorisationCheck
{
Blah = x.Blah
}).ToList();
EDIT2: Ma Solution
Je n'étais pas heureux avec l'anonyme de type méthode et s'en est allé de l'avant et a créé un modèle simple ne contenant que les propriétés requises pour être utilisé dans le viewmodel.
Changé le type de modèle.AuthorisationChecks
de
List<AuthorisationCheck> //List of Entities
à
List<AuthorisationCheckModel> //List of models
qui permet le code suivant pour le travail, et sans profilage, il semble beaucoup plus rapide que d'utiliser un type anonyme (et bien sûr, je ne jette pas d'une liste à deux reprises!).
model.AuthorisationChecks = (from ac in ctx.AuthorisationChecks
where wedNumbers.Contains(ac.WedNo)
orderby ac.WedNo, ac.ExpAuthDate, ac.ActAuthDate
select new AuthorisationCheckModel
{
Blah = x.Blah
}).ToList();
P. S. j'ai été une fois averti par un collègue (qui a l'habitude de travailler pour Microsoft) que ce n'est pas une bonne idée d'utiliser directement les Entités de cette manière, c'était peut être l'une des raisons pour lesquelles il a été la pensée de l', j'ai aussi remarqué un comportement étrange à l'aide des Entités directement dans les autres cas (principalement des corruptions).
model.AuthorisationChecks =
OriginalL'auteur Paul Zahra | 2015-03-11
Vous devez vous connecter pour publier un commentaire.
Si cette requête fonctionne très bien:
alors cela devrait aussi fonctionner:
et dans votre premier cas, vous n'avez pas besoin de projet de nouveau, vous pouvez affecter directement à modèle propeerty:
Mise à JOUR:
Comme il est De Linq to entities,vous devez faire quelque chose comme ceci en utilisant anonyme de type:
et puis:
OriginalL'auteur Ehsan Sajjad
Note: j'utilise généralement lambda expression à la place de l'API Fluent, mais la racine du problème doit être le même.
J'ai historiquement remarqué LINQ est incapable d'utiliser les classes C# pour Sélectionner états si l'origine de la source de données (c'est à dire
ctx
pour vous) est accessible par la traduction de votre requête dans SQL.En d'autres termes, il y a des problèmes lors de l'obtention de quelque chose à partir de la base de données et un moulage d'une classe personnalisée dans la même chaîne.
LINQ est assez intelligent qu'il ne fait pas exécuter immédiatement votre enchaîné les appels. Simplement en interne construit une requête, et en fait, quand vous accédez à vos résultats (c'est à dire récupérer la valeur de la mémoire), il exécute la requête.
Je suppose que c'est également la raison pour laquelle vous êtes confronté à cette erreur, parce que LINQ traduit tout (y compris la sélection) pour SQL, et échoue car il n'y a pas de SQL-façon de l'exprimer. En bref, LINQ ne peut pas faire un construit requête demi-SQL, demi-code. C'est soit tous en SQL, ou la totalité du code.
Habituellement, vous pouvez confirmer que c'est le cas en faisant d'abord un
List<>
de la table de base de données, puis d'exécuter exactement la même requête.Remarque: ce n'est pas une solution!
En prenant l'ensemble de la table en mémoire est trop intensif façon de contourner ce problème. Ça prouve juste que le point que le problème n'est pas rencontré de si la source de données est en mémoire, mais l'erreur ne peut se produire si c'est dans une base de données.
Il ya des façons que j'ai corrigé cela, bien que je n'ai jamais trouvé une manière uniforme à l'approche de ce problème (en général dépend de l'avis de mon code examinateur, si il aime le correctif ou pas)
En utilisant les types anonymes, vous pouvez sélectionner ce que vous voulez, et plus tard, il la jeta à la classe correcte. Vous pouvez utiliser exactement le même champs, faire un plus tard jeté plus facile à comprendre.
Si vous utilisez des expressions lambda au lieu de l'API fluent, vous pouvez appeler
.ToList()
après appliquant les filtres, mais avant l'appel de la.Select()
méthode. Cela garantit la requête sera exécutée, extraites de la base de données, et de mettre enList<>
dans la mémoire. À ce stade, vous pouvez appeler la.Select()
instruction en cours d'exécution dans le même problème.Malheureusement, mon expérience avec ce problème, c'est anecdotique. Je n'ai jamais été en mesure de confirmer officiellement mes soupçons quant à l'origine de ce problème; mais les solutions de contournement que j'ai mentionné devrait fonctionner comme je les ai appliquées à de nombreuses reprises dans le passé.
Si quelqu'un a une explication de la cause, je serais très intéressé à entendre!
Pas spécifiquement. J'ai utilisé un simple exemple avec de simples champs de démontrer l'idée. Changement de la classe et les champs par ceux qui sont appropriées à votre cas.
OriginalL'auteur Flater