Retrieve a simple subset of properties for all items in list
Usually, anon data types are used in the select
clause to return a specific subset of properties for each object in the collection.
we have the employee class
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
List<Employee> employees = // whatever ...
// we convert an Employee into an anon object type with a subset of properties
var employeeDetails = from emp in employees
select new { Id = emp.ID, Name = emp.Name };
How to map List of classes
// Method to show call usage.
public List<MappedUser> MapListOfUsers(List<User> users)
{
// option 1
List<MappedUser> mappedUsers = users.Select(user => MapSingleUser(user))
.ToList();
// option 2
List<MappedUser> mappedUsers2 =
(from user in users select MapSingleUser(user)).ToList();
}
method to encapsulate mapping itself
private MappedUser MapSingleUser(User user)
{
var mapped = new MappedUser
{
Id = user.Id,
Name = user.Name,
Email = user.Email
};
return mapped;
}
This provides easier and more legible than doing a foreach
to iterate everything.
How to filter list per properties (Where)
var adminUserTask = users
.AsParallel()
.Where(user => "admin".Equals(user.type.ToLower()))
.Select(async user => { return await ProcessAdmin(user);});
List<UserResults> results = (await Task.WhenAll(adminUserTask)).ToList();
How to select records based on another list (ids)
This is how to select a list of items, selecting them by id, based on another list of items
List<string> idList = // ...
var profiles = _context.UserProfiles
.Where(userProf => idList.Contains(userProf.Id));
How to order based on a dynamic parameter
// Direction is an Enum w. values ASC or DESC
private List<Person> SortPersons(Direction direction, List<Person> persons, Func<Person, string> sortBy)
{
if(direction.DESC)
{
return persons.OrderByDescending(sortBy.Invoke).ToList();
} else
{
return persons.OrderBy(sortBy.Invoke).ToList();
}
}
How to use it
var sortedPersons = SortPersons(direction, persons, person => person.Name);
How to use in async await env
We separate the linq query into Task and Execution. This executes this Task concurrently.
Single param lambda
remember that for lambdas with a single param where it comes from the same query, you don’t need to explicitely set it
this transforms
public List<int> FilterList(List<int> listToFilter, List<int> filterintList)
{
return listToFilter.Where(number => filteringList.Contains(number)).ToList();
}
How to filter list per properties (Where)
filter by properties in a nullable list and return true if there’s any row that match. If the list is null, it returns false.
return response.results?.rows
.Where(row => row.id == requestId && (row.owner == requestOwner || row.responsible == requestResponsible))
.Any() ?? false;
another example
var task = response.results.rows
.AsParallel()
.Where(row => "specifictype".Equals(row.type.ToLower()))
.Select(async row => {
if(row.type.Equals("specificType"))
{
return await Something(row, id, log);
} else
{
return row;
}
});
Methods worth a mention
Remove duplicates Distinct()
var task = response.results.rows
.AsParallel()
.Where(row => "specificType".Equals(row.type.ToLower()))
.Select(async row => { return await Something(row, id, log);});
Get the difference of two lists Except()
var list = listToFilter
.Except(filteringList)
.ToList();
First()
vs Single()
// gets the first element that matches and stops there
string list = listToFilter
.First(s => s.StartsWith("ohno"));
// gets the matching element, or throws an exception if there's more than 1
string list = listToFilter
.Single(s => s.StartsWith("ohno"));