Search code examples
c#asp.net-mvclambdabooleanlinq-group

Lambda Query GroupBy with boolean values


I have a number of instances where I need to return a data list that uses .GroupBy. In addition to dates and integers I also need to return Boolean values, which I cannot seem to do. An example model:

public class HolidayCheckList
{
    public DateTime startDate { get; set; }
    public DateTime endDate { get; set; }
    public int stafferId { get; set; }
    public bool startTime { get; set; }
    public bool endTime { get; set; }
}

Below is the controller as it is at present:

var model = _db.AnnualLeaves
    .Where(r => r.StartDate <= tTE && r.EndDate >= tTS)
    .GroupBy(r => r.tBooked) 
    .Select(m => new HolidayCheckList
    {
        startDate = m.Max(r => r.StartDate),
        endDate = m.Max(r => r.EndDate),
        stafferId = m.Min(r => r.StafferId)
    });

    return View(model.ToList());

This does what I need. However, in addition to the startDate and endDate I need to return the startTime and endTime, which are Boolean values, to the View. I don't know whether I need an aggregate operator I am not aware of, need to include in the .GroupBy statement or maybe need a nested query. No doubt it will be something far simpler.

I did consider changing the data type to an integer, but would like to know if there is a way of doing this "properly".

As an aside, is there a learning resource or documentation for lambda queries? I can find basic information but nothing that details how .GroupBy works, or what the aggregate operators are.


Solution

  • If you're certain that all of the startTime and endTime values will be the same (or you don't care), you could use .First to select the first item in the group's startTime and endTime values:

    var model = _db.AnnualLeaves
        .Where(r => r.StartDate <= tTE && r.EndDate >= tTS)
        .GroupBy(r => r.tBooked) 
        .Select(m => new HolidayCheckList
        {
            startDate = m.Max(r => r.StartDate),
            endDate = m.Max(r => r.EndDate),
            stafferId = m.Min(r => r.StafferId),
            startTime = m.Select(r => r.StartTime).First(),
            endTime = m.Select(r => r.EndTime).First()
        });
    

    A good resource for lambdas is the Lambda Expressions article on MSDN.

    The Aggregation Operations looks like a good overview of the various aggregate operations available in LINQ. Unfortunately the examples are in VB.NET though.