C# 如何在不迭代的情况下将 Linq 结果转换为 DTO 类对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15124931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:07:50  来源:igfitidea点击:

How can I convert Linq results to DTO class object without iteration

c#.netlinqentity-framework

提问by Dan

I'm building a Web API project that will be made available to third-party's and also used by my own web application/s. The Web API methods will return JSON representations of complex types/objects. These are pre-defined classes which I can make available to third-party's so they understand how the data is structured and can deserialize the JSON. I'll refer to these classes as DTO classes until someone corrects me.

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

I have the following auto-generated entity model (from database) well this is the User class anyway with a relationship to the Scan table (relationship can be ignored for the purpose of this question)...

我有以下自动生成的实体模型(来自数据库),这无论如何都是 User 类,它与 Scan 表有关系(出于这个问题的目的,可以忽略关系)...

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; }
}

And the following DTO class which I would like to return to the presentation layer as List (I don't think I should use IEnumerable for business to presentation?).

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

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

My business layer for this component currently looks like below. Using Linq to get users from the database and then parsing the results and returning a List<> of POCO Users.

我的这个组件的业务层目前如下所示。使用 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;
}

Parsing through the results like this seems inefficient, and I have seen that you can do this sort of thing in the Linq query without iteration (e.g. the answer in this question Mapping Linq Query results to a DTO class).

像这样解析结果似乎效率低下,我已经看到您可以在 Linq 查询中执行此类操作而无需迭代(例如这个问题中的答案Mapping Linq Query results to a DTO class)。

I'm unsure as to where/how I should implement IEnumerable to enable this type of Linq query on my objects, and am also unsure of how to write a query similar to the one in the referenced question above but for my much simpler scenario.

我不确定我应该在何处/如何实现 IEnumerable 以在我的对象上启用这种类型的 Linq 查询,并且我也不确定如何编写类似于上面引用问题中的查询但对于我的情况要简单得多的查询。

Thanks in advance for any help.

在此先感谢您的帮助。

P.S. Please ignore the fact that I am exposing Username and Password via Web API and also that I am returning all Users at once. Above is a simplified version of my code for the purpose of this question.

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

采纳答案by Mohammad Dehghan

The complete method could be:

完整的方法可能是:

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();
    }
}

You said you want the result "without iteration". Using LINQ also does not eliminate the iteration. You are not doing it in your code, but it really happens when you call the ToList()method.

你说你想要“没有迭代”的结果。使用 LINQ 也不会消除迭代。你没有在你的代码中这样做,但当你调用ToList()方法时它确实发生了。

回答by Reed Copsey

You can use LINQ to Objects to do the conversion:

您可以使用 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();
}

回答by Dustin Kingen

We can get really compact if we use AutoMapper.

如果我们使用AutoMapper ,我们可以变得非常紧凑。

Bootstrap the mapper in your repository:

在您的存储库中引导映射器:

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

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

Then it's pretty simple (and there's nothing wrong with returning IEnumerable).

然后就很简单了(返回 IEnumerable 也没什么问题)。

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

回答by user1574908

In my query I have parent table with multiple childs.

在我的查询中,我有多个孩子的父表。

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

In this when I was using the ToList()in the linq query it is giving the error. Now I am using the anonymous type in the linq query and convert it into the next query like this

在此,当我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();

Where teamMemberQueryResultis the resultset from the linq query.

teamMemberQueryResultlinq 查询的结果集在哪里。