Quelle est la cause de l’erreur Linq: cette méthode ne peut pas être traduite en expression de magasin

J’ai un tas de méthodes Linq to Entity qui ont la même instruction select, alors j’ai pensé que je serais intelligent et que je ferais cette distinction dans sa propre méthode pour réduire la redondance … Erreur…

cette méthode ne peut pas être traduite en une expression de magasin

Voici la méthode que j’ai créée …

public User GetUser(DbUser user, long uid) { return new User { Uid = user.uid, FirstName = user.first_name, LastName = user.last_name }; } 

Et j’appelle dans une méthode comme celle-ci …

 public User GetUser(long uid) { using (var entities = new myEntities()) { return entities.DbUsers.Where( x => x.uid == uid && x.account_status == ( short )AccountStatus.Active ). Select( x => GetUser( x, uid ) ).FirstOrDefault( ); } } 

UPDATE: voici le code qui fonctionne en ligne

 public User GetUser(long uid, long uid_user) { using (var entities = new myEntities()) { var q = from u in entities.DbUsers where u.uid == uid_user select new User { Uid = u.uid, FirstName = u.first_name, LastName = u.last_name, BigPicUrl = u.pic_big, Birthday = u.birthday, SmallPicUrl = u.pic_small, SquarePicUrl = u.pic_square, Locale = u.locale.Trim(), IsFavorite = u.FavoriteFriends1.Any(x => x.uid == uid), FavoriteFriendCount = u.FavoriteFriends.Count, LastWishlistUpdate = u.WishListItems.OrderByDescending(x => x.added).FirstOrDefault().added, Sex = (UserSex)u.sex }; var user = q.FirstOrDefault(); user.DaysUntilBirthday = user.Birthday.DaysUntilBirthday(); return user; } } 

L’erreur est sur place, vous ne pouvez pas traduire cela en une requête T-SQL (ou P-SQL).

Vous devez vous assurer que vous avez exécuté la requête avant d’essayer de l’hydrater dans un autre type.

Restez simple, utilisez une méthode d’extension. C’est ce qu’ils sont là pour.

 public static User ToUserEntity(this DbUser user) { return new User { Uid = user.uid, FirstName = user.first_name, LastName = user.last_name }; } 

Puis dans votre DAL:

 public User GetUser(long uid) { User dbUser; using (var entities = new myEntities()) { dbUser = entities.DbUsers .Where( x => x.uid == uid && x.account_status == (short)AccountStatus.Active ) .FirstOrDefault(); // query executed against DB } return dbUser.ToUserEntity(); } 

Voyez comment j’hydrate le POCO en un object après la suppression du contexte? De cette façon, vous vous assurez que EF a terminé son travail d’expression avant de tenter de s’hydrater en object personnalisé.

Aussi, je ne sais pas pourquoi vous passez à cette méthode, elle n’est même pas utilisée.

Sur une note supplémentaire, vous ne devriez pas avoir besoin de faire ce genre de chose (projet EF POCO dans vos propres objects).

Si vous le faites, c’est un bon cas pour les POCO personnalisés (mappez les tables directement dans vos POCO personnalisés, n’utilisez pas la génération de code).

Cette expression fonctionnera pour donner le résultat souhaité (un peu). Je n’ai toujours pas compris comment passer des variables supplémentaires dans les instructions select …

  ..... .Select(GetUser).FirstOrDefault() static readonly Expression> GetUser = (g) => new User { Uid = g.uid, FirstName = g.first_name, LastName = g.last_name, BigPicUrl = g.pic_big, Birthday = g.birthday, SmallPicUrl = g.pic_small, SquarePicUrl = g.pic_square, Locale = g.locale.Trim(), //IsFavorite = g.FavoriteFriends1.Any(x=>x.uid==uid), FavoriteFriendCount = g.FavoriteFriends.Count, LastWishlistUpdate = g.WishListItems.OrderByDescending( x=>x.added ).FirstOrDefault().added }; 

Vous ne pouvez pas faire cela car la méthode getUser ne peut pas être convertie en une instruction TSQL. si vous renvoyez d’abord votre DBUser et que vous l’utilisez ensuite comme premier paramètre de la méthode GetUser , vous GetUser exécution et une fois que vous avez DBUser vous pouvez le transmettre à GetUser

Peut-être que vous pouvez essayer ceci:

 public User GetUser(long uid) { using (var entities = new myEntities()) { return GetUser( entities.DbUsers .Where( x => x.uid == uid && x.account_status == (short)AccountStatus.Active ) .FirstOrDefault(), uid); } } 

MODIFIER

Puisque vous dites que cela échoue encore, pourrait-il être la cause de l’énum ??

 public User GetUser(long uid) { using (var entities = new myEntities()) { short status = (short)AccountStatus.Active; return GetUser( entities.DbUsers .Where( x => x.uid == uid && x.account_status == status ) .FirstOrDefault(), uid); } }