2010-09-21 24 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

相關問題