Reputation: 519
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.
Upvotes: 23
Views: 56962
Reputation: 1
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
List<TeamModel.TeamWithMembers> teamMemberList = teamMemberQueryResult.AsEnumerable().Select(item =>
new TeamModel.TeamWithMembers() {
TeamId=item.TeamId,
TeamName=item.TeamName,
TeamMembers=item.TeamMembers.ToList()
}).ToList();
Where teamMemberQueryResult
is the resultset from the linq query.
Upvotes: -1
Reputation: 21245
We can get really compact if we use AutoMapper.
Bootstrap the mapper in your repository:
Mapper.CreateMap<AutoGenNamespace.User, DtoNamespace.User>();
Then it's pretty simple (and there's nothing wrong with returning IEnumerable).
public IEnumerable<User> Get()
{
using (var db = new MyContext())
{
return (from u in db.Users
orderby u.FirstName
select Mapper.Map(u)).AsEnumerable();
}
}
Upvotes: 2
Reputation: 18443
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.
Upvotes: 41
Reputation: 564403
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();
}
Upvotes: 9