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

.net c# entity-framework linq

Question

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.

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)...

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?).

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.

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).

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.

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.

1
20
5/23/2017 12:34:39 PM

Accepted Answer

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.

36
2/28/2013 12:07:18 AM

Popular Answer

You can use LINQ to Objects to do the conversion:

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow