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

.net c# entity-framework linq

Question

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 séparerais cela dans sa propre méthode pour réduire la redondance ... mais quand j'ai essayé d'exécuter le code, j'ai obtenu ce qui suit 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;
            }
        }

Réponse populaire

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 objet 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 objet personnalisé.

De plus, 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 objets).

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).



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow