2010-09-21 48 views
6

我有一堆Linq to Entity方法具有相同的select语句,所以我认为我会聪明并将它分离出来以减少冗余的自己的方法...但是当我试图运行代码时,我得到了下面的错误......什么导致Linq错误:这种方法不能被转换成商店表达式?

this method cannot be translated into a store expression

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

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

回答

0

你不能这样做,因为的getUser方法不能转换为任何TSQL语句的代码。 如果你先回你的DBUSER,然后用它作为GetUser方法的第一个参数,那么你正迫使它来执行,一旦你有你DBUser,你可以把它传递给GetUser

也许你可以试试这个:

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

我试过这种技术,但仍然失败 – 2010-09-21 04:57:54

+0

为什么你有DbUser和用户呢? EF的实体是否应该成为你的域名实体?它看起来像User是DbUser的一个虚拟版本,为什么不只是在DBUsers上运行? – 2010-09-21 05:11:18

+0

我猜DbUser是EF POCO,用户是他的自定义业务对象。不过,我更喜欢直接映射到我的自定义POCO。离开中间人。 – RPM1984 2010-09-21 05:13:26

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的,不使用代码生成)。

+0

好吧,我在查询的一大块中使用了uid,这里我没有显示(这并没有影响错误)。当我有内联的这个陈述时,它工作得很好。但是,如果我将代码移入自己的方法,如果失败。为什么编译器不能暗示该表达式属于EF语句。后来我知道我可以保存这个对象,但是我有几个需要在db上下文中操作的字段。他们只是一遍又一遍地重复(并且他们工作正常)。我真的不明白为什么你不能提取这个功能到自己的方法。 – 2010-09-21 05:30:27

+0

@wcpro - 你能在内联代码中显示代码吗?为了创建查询表达式,我会非常感兴趣地看到Entity Framework如何设法“猜测”User(随机CLR对象)和DbUser(EF对象)之间的关系。 – RPM1984 2010-09-21 05:36:30

+0

无论如何,你是否尝试了我的答案 - 它应该工作(除非你有一个枚举问题,正如卡洛斯所说的那样) – RPM1984 2010-09-21 05:52:26

3

这个表达式会产生所需的结果(有点)我还没有想出如何在select语句中传递额外的变量......

..... .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 
     }; 
+0

我真的很喜欢这个原因,你可以在枚举之前在linq查询中使用它,因此它可以与列表一起使用。 – tkerwood 2013-02-13 03:59:22

相关问题