L'entité ne peut pas être construits en une requête LINQ to entities
Il y a un type d'entité appelée produit qui est généré par entity framework.
J'ai écrit cette requête
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new Product { Name = p.Name};
}
Le code ci-dessous déclenche le message d'erreur suivant :
"L'entité ou de type complexe de la Boutique.Le produit ne peut pas être construits en une
Requête LINQ to entities"
var products = productRepository.GetProducts(1).Tolist();
Mais quand j'utilise select p
au lieu de select new Product { Name = p.Name};
il fonctionne correctement.
Comment puis-je préforme personnalisé sélectionnez la section?
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas (et ne devrait pas être capable de) projet sur le mapping de l'entité. Vous pouvez, cependant, un projet sur un type anonyme ou sur un DTO:
Et votre méthode, vous obtiendrez une Liste de DTO est.
ToList()
"récupère les données dans une Liste".Vous pouvez projeter dans un type anonyme, puis à partir de ce type de modèle
Modifier: je vais être un peu plus précis, puisque cette question a obtenu beaucoup d'attention.
Vous ne pouvez pas le projet dans le type de modèle directement (EF restriction), donc il n'y a pas moyen de contourner cela. Le seul moyen est de se projeter dans un type anonyme (1ère itération), et puis pour le type de modèle (2ème itération).
S'il vous plaît être conscient que lorsque vous charger partiellement les entités de cette manière, ils ne peuvent pas être mis à jour, de sorte qu'ils doivent rester isolés, tels qu'ils sont.
Je n'ai jamais tout à fait comprendre pourquoi ce n'est pas possible, et les réponses sur ce fil ne donne pas de bonnes raisons contre elle (surtout parler partiellement chargées de données). Il est exact que, dans l'état partiellement chargé de l'entité ne peut pas être mis à jour, mais ensuite, cette entité serait détachée, de manière accidentelle tente de sauver ne serait pas possible.
Envisager la méthode que j'ai utilisé ci-dessus: nous avons encore partiellement chargées modèle entité comme un résultat. Cette entité est détachée.
Considérer cette wish-à-exister) code possible:
Cela pourrait également résulter en une liste de détaché entités, de sorte que nous n'aurions pas besoin de faire deux itérations. Un compilateur pourrait être intelligent pour voir que AsNoTracking() a été utilisé, ce qui entraînera détaché entités, de sorte qu'il pourrait nous permettre de le faire. Si, toutefois, AsNoTracking() a été omis, il pourrait jeter la même exception qu'il est en train de jeter maintenant, pour nous avertir que nous devons être assez précis sur le résultat que nous voulons.
Il y a un autre moyen que j'ai trouvé fonctionne, vous devez créer une classe qui dérive de votre catégorie de Produit et l'utiliser. Par exemple:
Ne sais pas si c'est "autorisé", mais il fonctionne.
ALTER TABLE [dbo].[Product] ADD [Discriminator] [nvarchar](128) NOT NULL DEFAULT ''
[NotMapped]
comme un attribut de la classe dérivéeIci est une façon de le faire sans le déclarer supplément de classe:
Cependant, c'est seulement être utilisé si vous souhaitez combiner plusieurs entités en une seule entité. Au-dessus de la fonctionnalité (simple produit à la cartographie) se fait comme ceci:
Un autre moyen simple 🙂
.ToList
dans la requête, il est exécuté et a tiré des données du serveur, alors quel est le point de recommencerAsQueryable
?.Vous pouvez l'utiliser et il convient de travail --> Vous devez utiliser
toList
avant de faire la nouvelle liste à l'aide de select:En réponse à l'autre question qui a été marqué comme un double (voir ici) j'ai trouvé une solution simple et rapide basé sur la réponse de Soren:
Note:
Cette solution ne fonctionne que si vous avez une propriété de navigation (clé étrangère) sur la Tâche de la classe (ici appelé "l'Incident").
Si vous n'avez pas cela, vous pouvez simplement utiliser l'une de l'autre posté des solutions avec "AsQueryable()".
Vous pouvez résoudre ce problème en utilisant des Objets de Transfert de Données (DTO s).
Ces sont un peu comme les viewmodels où vous avez mis dans les propriétés dont vous avez besoin et vous pouvez mapper manuellement dans votre contrôleur ou à l'aide de solutions tierces comme AutoMapper.
Avec DTO vous pouvez :
J'ai appris cela à l'école cette année et c'est un outil très utile.
Si vous êtes en utilisant Entity framework, puis essayez de retirer la propriété de DbContext qui utilise la complexité de votre modèle d'Entité
J'ai eu le même problème lors de la cartographie de multiples modèle dans un viewmodel de l'Entité nommée
Suppression de l'entrée de DbContext corrigé mon erreur.
si vous êtes l'Exécution de
Linq to Entity
vous ne pouvez pas utiliser laClassType
avecnew
dans leselect
fermeture de la requêteonly anonymous types are allowed (new without type)
prendre regardez cet extrait de mon projet
de vous avez ajouté l'
new keyword
dans Sélectionnez la fermeture, même sur lecomplex properties
vous aurez obtenu cette erreurcar il sera transformé pour l'instruction sql et exécuté sur SqlServer
donc quand puis-je utiliser
new with types
surselect
fermeture?vous pouvez l'utiliser si vous vous faites affaire avec
LINQ to Object (in memory collection)
après que j'ai exécuté
ToList
sur requête, il est devenuin memory collection
nous pouvons donc utilisernew ClassTypes
en sélectionnerseulement ajouter de la AsEnumerable() :
Dans de nombreux cas, la transformation n'est pas nécessaire. Pense que pour la raison que vous voulez fortement Liste type, et d'évaluer si vous voulez juste les données, par exemple, dans un service web ou pour l'afficher. Il n'a pas d'importance ce type.
Vous avez juste besoin de savoir comment les lire et vérifier que c'est identique pour les propriétés définies dans l'anonyme de type que vous avez défini. C'est l'optimun scénario, cause de quelque chose que vous n'avez pas besoin de tous les champs d'une entité, et c'est la raison anonyme de type n'existe.
Un moyen simple est de faire ceci:
vous pouvez ajouter AsEnumerable à votre collection comme le suivi :