2013-02-27 68 views
18

我正在構建一個Web API項目,該項目可供第三方使用,也可供我自己的Web應用程序使用。 Web API方法將返回複雜類型/對象的JSON表示。這些是預先定義的類,我可以向第三方提供,以便他們瞭解數據的結構以及可以反序列化JSON。我會將這些課程稱爲DTO課程,直到有人糾正我爲止。如何將Linq結果轉換爲DTO類對象而無需迭代

我有以下的自動生成的實體模型(來自數據庫)以及這是User類反正用的掃描表的關係(關係可以爲這個問題的目的被忽略)...

public partial class User 
{ 
    public User() 
    { 
     this.Scans = new HashSet<Scan>(); 
    } 

    public int Id { get; set; } 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public bool Active { get; set; } 

    public virtual ICollection<Scan> Scans { get; set; } 
} 

以下DTO類,我想返回到表示層作爲列表(我不認爲我應該使用IEnumerable業務來演示?)。

public class User 
{ 
    public int Id; 
    public string Username; 
    public string Password; 
    public bool Active; 
} 

此組件的業務層當前如下所示。使用Linq從數據庫中獲取用戶,然後解析結果並返回POCO用戶列表<>。

public List<User> Get() 
{ 
    List<User> userList = new List<User>(); 

    using (var db = new MyContext()) 
    { 
     var query = from u in db.Users 
        orderby u.FirstName 
        select u; 

     foreach (var item in query) 
     { 
      User user = new User(); 
      user.Id = item.pkUser; 
      user.Username = item.Username; 
      user.Password = item.Password; 
      user.Active = item.Active; 

      userList.Add(user); 
     } 
    } 

    return userList; 
} 

通過解析結果像這似乎效率不高,我已經看到了你可以做這樣的事情在LINQ查詢不重複(例如,在該問題Mapping Linq Query results to a DTO class答案)。

我不確定在哪裏/如何實現IEnumerable以在我的對象上啓用此類型的Linq查詢,並且我也不確定如何編寫類似於上述引用問題中的查詢的查詢,但對於我更簡單的情況。

在此先感謝您的幫助。

P.S.請忽略我通過Web API公開用戶名和密碼的事實以及我一次返回所有用戶的事實。以上是針對此問題的代碼的簡化版本。

+0

無論發生什麼,你都會迭代。你可以使用'Enumerable.Select'來轉換你的列表。 – Romoku 2013-02-27 23:58:57

回答

33

完整的方法可能是:

public List<User> Get() 
{ 
    using (var db = new MyContext()) 
    { 
     return (from u in db.Users 
       orderby u.FirstName 
       select new User() 
       { 
        Id = u.pkUser, 
        Username = u.Username, 
        Password = u.Password, 
        Active = u.Active 
       }).ToList(); 
    } 
} 

你說你想要的結果「不重複」。使用LINQ也不會消除迭代。你沒有在你的代碼中執行它,但是當你調用ToList()方法時真的發生了。

+0

我打算用最簡單和最靈活的答案穿着最好的衣服。謝謝。 – Dan 2013-02-28 00:15:52

9

您可以使用LINQ到對象進行轉換:

using (var db = new MyContext()) 
{ 
    var query = from u in db.Users 
       orderby u.FirstName 
       select u; 

    return query.AsEnumerable().Select(item => 
       new User 
        { 
         Id = item.pkUser, 
         Username = item.Username, 
         Password = item.Password, 
         Active = item.Active 
        }).ToList(); 
} 
3

如果我們使用AutoMapper,我們可以變得非常緊湊。

引導您的存儲庫中的映射:

Mapper.CreateMap<AutoGenNamespace.User, DtoNamespace.User>();

那麼它很簡單(並沒有什麼不妥返回IEnumerable的)。

public IEnumerable<User> Get() 
{ 
    using (var db = new MyContext()) 
    { 
     return (from u in db.Users 
       orderby u.FirstName 
       select Mapper.Map(u)).AsEnumerable(); 
    } 
} 
+0

我不同意「*沒有錯*」。某物*可能會出錯! 'var list = Get();'然後不止一次遍歷列表。 – 2013-02-28 00:10:56

+0

@ MD.Unicorn然後'var list = Get().ToList();'解決了這個問題。你知道你從簽名的方法中得到一個枚舉。 – Romoku 2013-02-28 00:13:08

+0

是的,我知道!但你確定丹知道嗎?! :-) – 2013-02-28 00:14:39

-1

在我的查詢中,我有父表與多個孩子。

public class TeamWithMembers 
     { 
      public int TeamId { get; set; } 
      public string TeamName { get; set; } 
      public string TeamDescription { get; set; } 
      public List<TeamMembers> TeamMembers { get; set; } 
     } 

在這個時候我用的是ToList()在LINQ查詢它給錯誤。 現在我正在使用LINQ查詢匿名類型,並將其轉換成一個查詢這樣

List<TeamModel.TeamWithMembers> teamMemberList = teamMemberQueryResult.AsEnumerable().Select(item => 
new TeamModel.TeamWithMembers() { 
    TeamId=item.TeamId, 
    TeamName=item.TeamName, 
    TeamMembers=item.TeamMembers.ToList() 
}).ToList(); 

哪裏teamMemberQueryResult從LINQ查詢結果集。

相關問題