是什么导致Linq错误:此方法无法转换为商店表达式?

时间:2010-09-21 04:36:58

标签: c# .net linq entity-framework

我有一堆Linq to Entity方法具有相同的select语句,所以我认为我会聪明并将其分离到它自己的方法来减少冗余...但是当我试图运行代码时,我得到以下错误......

  

此方法无法翻译成   商店表达

这是我创建的方法......

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

我正在调用这样的方法......

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( );
    }
}

更新:这是内联工作的代码

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;
            }
        }

3 个答案:

答案 0 :(得分:9)

错误点亮,您无法将其转换为T-SQL(或P-SQL)查询。

在尝试将查询水合成其他类型之前,您需要确保已执行查询。

保持简单,使用扩展方法。这就是他们的目的。

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

然后在你的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();
}

在上下文被处理后,看看我如何将POCO水合成一个对象?这样,在尝试水合成自定义对象之前,确保EF已完成表达式工作。

此外,我不知道为什么你将uid传递给那个方法,它甚至没有被使用。

另外请注意,你不应该需要来做这种事情(将EF POCO投射到你自己的对象中)。

如果你这样做,这是自定义POCO的好例子(将表格直接映射到你的自定义POCO,不要使用代码生成)。

答案 1 :(得分:3)

这个表达式可以提供所需的结果(有些)我仍然没有想出如何在选择语句中传入其他变量......

  ..... .Select(GetUser).FirstOrDefault()        

static readonly Expression<Func<DbUser, User>> 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
        };

答案 2 :(得分:0)

您无法执行此操作,因为无法将getUser方法转换为任何TSQL语句。 如果您首先返回DBUser然后将其用作GetUser方法的第一个参数,那么您将强制执行它,一旦有了DBUser,您就可以将其传递给GetUser < / p>

也许你可以试试这个:

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);
    }
}

修改

既然你说它仍然失败可能是因为枚举?

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);
    }
}