如何在不迭代的情况下将Linq结果转换为DTO类对象
我正在构建一个Web API项目,该项目将提供给第三方并由我自己的Web应用程序使用。 Web API方法将返回复杂类型/对象的JSON表示。 这些是我可以提供给第三方的预定义类,因此他们了解数据的结构,并可以反序列化JSON。 我会将这些类称为DTO类,直到有人纠正我为止。
我有以下自动生成的实体模型(来自数据库),这是用户类无论如何与扫描表的关系(为了这个问题可以忽略关系)…
public partial class User { public User() { this.Scans = new HashSet(); } public int Id { get; set; } public string Username { get; set; } public string Password { get; set; } public bool Active { get; set; } public virtual ICollection Scans { get; set; } }
以下DTO类我想以列表的forms返回到表示层(我不认为我应该使用IEnumerable进行业务演示?)。
public class User { public int Id; public string Username; public string Password; public bool Active; }
此组件的业务层目前如下所示。 使用Linq从数据库中获取用户,然后解析结果并返回POCO用户的List 。
public List Get() { List userList = new List(); 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查询中做这种事情(例如,将Linq查询结果映射到DTO类的问题中的答案)。
我不确定我应该在哪里/如何实现IEnumerable以在我的对象上启用这种类型的Linq查询,并且我也不确定如何编写类似于上面引用的问题中的查询但是对于我更简单的场景。
在此先感谢您的帮助。
PS请忽略我通过Web API公开用户名和密码的事实,以及我一次性返回所有用户的事实。 以上是我的代码的简化版本,用于此问题。
完整的方法可以是:
public List 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()
方法时确实会发生这种情况。
您可以使用LINQ to Objects进行转换:
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(); }
如果我们使用AutoMapper,我们可以变得非常紧凑。
在您的存储库中引导映射器:
Mapper.CreateMap
然后它非常简单(并且返回IEnumerable没有任何问题)。
public IEnumerable Get() { using (var db = new MyContext()) { return (from u in db.Users orderby u.FirstName select Mapper.Map(u)).AsEnumerable(); } }
在我的查询中,我有父表与多个子。
public class TeamWithMembers { public int TeamId { get; set; } public string TeamName { get; set; } public string TeamDescription { get; set; } public List TeamMembers { get; set; } }
在我使用linq查询中的ToList()
,它给出了错误。 现在我在linq查询中使用匿名类型并将其转换为下一个查询
List teamMemberList = teamMemberQueryResult.AsEnumerable().Select(item => new TeamModel.TeamWithMembers() { TeamId=item.TeamId, TeamName=item.TeamName, TeamMembers=item.TeamMembers.ToList() }).ToList();
其中teamMemberQueryResult
是linq查询的结果集。