21

我正在构建一个 Web API 项目,该项目可供第三方使用,也可供我自己的 Web 应用程序使用。Web API 方法将返回复杂类型/对象的 JSON 表示。这些是我可以提供给第三方的预定义类,以便他们了解数据的结构并可以反序列化 JSON。在有人纠正我之前,我会将这些类称为 DTO 类。

我有以下自动生成的实体模型(来自数据库),这无论如何都是与 Scan 表有关系的 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; }
}

以及我想作为 List 返回到表示层的以下 DTO 类(我认为我不应该使用 IEnumerable 进行业务演示?)。

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

我的这个组件的业务层目前如下所示。使用 Linq 从数据库中获取用户,然后解析结果并返回 POCO 用户的 List<>。

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 查询,并且我也不确定如何编写与上面引用的问题中的查询类似的查询,但对于我更简单的场景。

提前感谢您的帮助。

PS 请忽略我通过 Web API 公开用户名和密码以及我同时返回所有用户的事实。以上是我的代码的简化版本,用于此问题。

4

4 回答 4

37

完整的方法可以是:

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()方法时它确实发生了。

于 2013-02-28T00:00:17.580 回答
9

您可以使用 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();
}
于 2013-02-27T23:58:48.967 回答
2

如果我们使用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();
    }
}
于 2013-02-28T00:07:47.770 回答
-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();

teamMemberQueryResultlinq 查询的结果集在哪里。

于 2016-01-13T00:57:28.450 回答