keitn
keitn

Reputation: 1298

Passing Aggregation to a Linq Query

I have several queries that are pretty much the same except that the aggregation is different. I am trying to create a method where I can pass the aggregation function. My effort so far looks like

public void ExecQuery(Func<IEnumerable<testtable>, float?> filter)
{           
    var results = from a in testtable
                  group a by a.TransactionDate.Month into j
                  select new
                  {
                      Month = j.Key,                              
                      Total = filter
                  };
}

I would then like to be able to call it using

ExecQuery(c => c.Sum(a=>a.Price));      
ExecQuery(c => c.Count());

I think I am pretty close.

Upvotes: 2

Views: 190

Answers (1)

Ali Ezzat Odeh
Ali Ezzat Odeh

Reputation: 2163

Your too close friend, try the following it should fix things for you:

 public class testtable
 {
    public DateTime TransactionDate { get; set; }

    public float? Price { get; set; }
 }

 public List<testtable> tests = new List<testtable>();

Your method now should look like:

public void ExecQuery(Func<IEnumerable<testtable>, float?> filter)
{
   var results = from a in tests
   group a by a.TransactionDate.Month into j
   select new
   {
      Month = j.Key,
      Total = filter(j)//actually this the little update needed here
   };
}

In order to test our code:

    static void Main(string[] args)
    {
        tests.Add(new testtable() { Price = 10, TransactionDate =new DateTime(2018,1,1,0,0,0) });
        tests.Add(new testtable() { Price = 20, TransactionDate = new DateTime(2018, 1, 2, 0, 0, 0) });
        tests.Add(new testtable() { Price = 30, TransactionDate = new DateTime(2018, 3, 1, 0, 0, 0) });
        tests.Add(new testtable() { Price = 40, TransactionDate = new DateTime(2018, 3, 2, 0, 0, 0) });
        ExecQuery(c => c.Sum(a => a.Price));
        ExecQuery(c => c.Count());
    }

Then the result of the method should be:

for the sum : { Month = 1, Total = 30.0 } and { Month = 3, Total = 70.0 }

for the count: { Month = 1, Total = 2.0 } and { Month = 3, Total = 2.0 }

Also one comment here please use decimal for price it is more common and better for financial quantities.

Hope this helps :)

Upvotes: 5

Related Questions