2014-10-30 45 views
0

我不找任何一個解決的稱號,我尋求建議純屬提到的問題,因爲我有固定的我自己但我想得到一些專家的意見,我有一個方法,加載用戶的詳細信息並返回UserProfile()類實體或複雜類型「WebServices.UserProfile」不能在LINQ構建以查詢實體

如下圖所示,運行與下面的代碼的應用程序時的關鍵點我得到上述錯誤。

public UserProfile LoadUserDetails(Int64 userId) 
    { 
     var userProfile = new UserProfile(); 

     using (var context = new Context()) 
     { 
      userProfile = (from p in context.UserProfile 
          where p.UserId == userId 
          select new UserProfile() 
          { 
           UserId = userId, 
           Firstname = p.Firstname, 
           Surname = p.Surname, 
           Username = p.Username, 
           CurrentlyOnline = p.CurrentlyOnline, 
           JoinedDate = p.JoinedDate, 
           UserLocation = p.UserLocation 
          }).FirstOrDefault(); 

      context.Dispose(); 
     } 
     return userProfile; 
    } 

如果我添加.AsEnumerable()它的工作原理如下圖所示

public UserProfile LoadUserDetails(Int64 userId) 
    { 
     var userProfile = new UserProfile(); 

     using (var context = new Context()) 
     { 
      userProfile = (from p in context.UserProfile.AsEnumerable() 
          where p.UserId == userId 
          select new UserProfile() 
          { 
           UserId = userId, 
           Firstname = p.Firstname, 
           Surname = p.Surname, 
           Username = p.Username, 
           CurrentlyOnline = p.CurrentlyOnline, 
           JoinedDate = p.JoinedDate, 
           UserLocation = p.UserLocation 
          }).FirstOrDefault(); 

      context.Dispose(); 
     } 
     return userProfile; 
    } 

現在,當上面提到我用下面的代碼固定的錯誤,純粹是因爲每一個解決方案,我看了更適合於這種方法,我將用戶加載到臨時類中,創建UserProfile()的新實例並從臨時類中填充相關變量。

public UserProfile LoadUserDetails(Int64 userId) 
    { 
     var userProfile = new UserProfile(); 

     using (var context = new Context()) 
     { 
      var t = (from p in context.UserProfile 
        where p.UserId == userId 
        select new 
        { 
         UserId = userId, 
         Firstname = p.Firstname, 
         Surname = p.Surname, 
         Username = p.Username, 
         CurrentlyOnline = p.CurrentlyOnline, 
         JoinedDate = p.JoinedDate, 
         UserLocation = p.UserLocation 
        }).FirstOrDefault(); 

      userProfile = new UserProfile 
      { 
       UserId = userId, 
       Firstname = t.Firstname, 
       Surname = t.Surname, 
       Username = t.Username, 
       CurrentlyOnline = t.CurrentlyOnline, 
       UserLocation = t.UserLocation, 
       JoinedDate = t.JoinedDate 
      }; 

      context.Dispose(); 
     } 
     return userProfile; 
    } 

所以我給你的問題是什麼是最好的方法代碼示例2或3?考慮性能。

我正在學習實體框架6所以最好我想正確地使用它。

謝謝

回答

0

您使用.AsEnumerable()在正確的軌道上。我會做這樣的:

public UserProfile LoadUserDetails(int userId) { 
    using (var context = new Context()) { 
     userProfile = context.UserProfile 
      .FirstOrDefault(x => x.UserId == userId); 
    } 
} 

你可以先做.Where(...)然後.FirstOrDefault(),但你可以在通話中添加,其中標準來.FirstOrDefault(...)

如果你不想選擇UserProfile類的所有列,那麼您應該創建用於該目的的獨立的數據holder類。但是你不能在你的linq查詢中使用那個類。您的查詢會變成類似於:

public SmallUserProfile LoadUserDetails(int userId) { 
    using (var context = new Context()) { 
     userProfile = context.UserProfile 
      .Where(x => x.UserId == userId) 
      .Select(x => new SmallUserProfile { 
       UserId = x.userId, 
       // etc... 
      }) 
      .AsEnumerable() 
      .Select(x => new SmallUserProfile { 
       UserId = x.userId, 
       // etc... 
      }) 
      .FirstOrDefault(); 
    } 
} 

但是,這第二個版本基本上與您的一個版本相同。

+0

好吧,我想我會擴展到只返回我需要的7個字段,因爲我並不需要UserProfile中的所有15列,並且從我教過的內容中只選擇需要幫助的性能列。 – 2014-10-30 10:49:29

+0

作爲一般指導原則,只有選擇你需要的東西。但是如果你從表中選擇一行,我認爲你獲得的表現相當不錯。另一方面,如果你用這個查詢方法調用數百萬次... – Maarten 2014-10-30 10:51:00

+0

這就是我想要解決的問題,因爲我可以讓5000多個用戶打這個應用程序,所以我非常理想並試圖實現一個合適的方法,因爲我想要的最後一件事是應用程序停下來。 – 2014-10-30 10:57:19

0

我認爲性能不是問題,但代碼非常冗長。我會考慮使用Find function on DbSet來執行以下操作。此代碼假設context.UserProfile屬於DbSet類型,如果不是這種情況,則需要將其轉換爲DbSet,並且UserProfile上的UserId屬性是實體的密鑰。

public UserProfile LoadUserDetails(Int64 userId) 
{ 
    // Assuming context.UserProfile is/can be converted to DbSet<UserProfile> 
    // and the userId is the Key to the Entity 

    using (var context = new Context()) 
    { 
     return context.UserProfile.Find(userId); 
    } 
} 

這將大致做你的代碼在做什麼。如果沒有匹配主鍵,您可能需要執行一些檢查/錯誤處理。

+0

所以你個人認爲你會說你給出的代碼示例會更好,即從性能的角度來看?我會添加一些錯誤,儘管 – 2014-10-30 10:33:37

+0

也來自我個人的經驗,我不想從UserProfile表中選擇所有的東西,因爲我只需要當前有問題的7列,而UserProfile表有大約15個coloumns @ AlexC – 2014-10-30 10:46:20

+1

描述那些7列和15列的成本,看看是否有任何可衡量的差異,我希望看到結果。然後根據您編寫的附加代碼來衡量維護成本。還要考慮當LoadUserDetails返回的使用UserProfile對象的代碼訪問您決定使用默認值填充的屬性時可能發生的細微錯誤的代價。 – AlexC 2014-10-30 12:06:17

相關問題