Généralement ce que je fais dans ces cas la, c'est que mes entités Linq To Entities (qui sont des POCO) sont partagés par toutes les couches. C'est une couche transversale.
Après ce que tu fais est tout à fait valable mais plus complexe à mettre en place.
En tout cas, ca n'empeche qu'il faut bien comprendre comment marche linq to entities et tout se joue entre IQueryable<T> et IEnumerable<T>.
Explications:
Lorsque tu utilises Context.user, tu peux remarquer que cette collection implémente à la fois IQueryable<T> et IEnumerable<T>. De plus tu remarques que lorsque tu prends un opérateur comme Select(), le paramètre qu'il prend est une expression.
Tant que tu trimballes des Select, Where, etc sur un IQueryable, cela veut dire que cela va être traduit en SQL derrière par le provider. (Le provider Linq To Entities va traduire les Expressions en SQL, c'est d'ailleurs pour ca que ce sont des Expression<Func<T>> et non des Func<T>.)
Au bout d'un moment, lorsque tu fais un ToList() ou un AsEnumerable(). La requete est déclenchée, les données sont récupérées et le mappage est effectué. Ce qui signifie qu'à ce moment la, tu manipules des objets et plus des lignes SQL. Lorsque tu fais ton Select, il essaye de le traduire en SQL et n'y arrive pas. Il faudrait que juste avant tu fasses un AsEnumerable().
Par exemple, pour le GetAll():
1 2 3 4 5 6 7 8
| Context.user.AsEnumerable() //declenche la requete SQL
.Select(u => new UserEntity
{
Id = u.id_user,
Lastname = u.lastname,
Firstname = u.firstname
})
.ToList(); |
Pour le Get(id) attention! Tu es tombé dans un piège de débutant avec Linq To SQL (ou Entities). Car si on applique la même solution:
1 2 3 4 5 6 7 8 9 10
| return Context.user
.Where(u => u.id_user.Equals(id))
.AsEnumerable()
.Select(u => new UserEntity
{
Id = u.id_user,
Lastname = u.lastname,
Firstname = u.firstname
})
.FirstOrDefault(); |
Catastrophe! De gros problèmes de performance! Car le FirstOrDefault() est fait en mémoire et donc si Where laisse passer 5000lignes, les 5000lignes seront rapatriés de la base vers la mémoire. C'est seulement une fois mappé que le First intervient.
Je te suggère ceci plutot:
1 2 3 4 5 6 7 8
| var user = Context.user
.FirstOrDefault(u => u.id_user.Equals(id));
return new UserEntity
{
Id = user.id_user,
Lastname = user.lastname,
Firstname = user.firstname
}); |
Partager