The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








I heart FeedBurner

Latest Diggs - Programming

Computers Blogs - Blog Top Sites

Site Hits

Total: 3,825,585
since: 19 Jan 2005

CLINQ v1.1.0.0 - New and Improved with Aggregation!

posted Wed 16 Apr 08

Continuous LINQ, if you haven't already heard, is a project that I started and put up on CodePlex to address the issue of static LINQ queries. Without something like CLINQ, every LINQ query you write is static. Once GetEnumerator() is invoked on the query expression, it is no longer associated with the collection that was the source of the query. This means that if you query for a list of a customer's orders from the OrderMaster collection at 10:00am, then your results query will be completely unaware of any new orders added to the order master anytime after 10:00am. People usually get around this by periodically rebuilding the result set in the background on a timer or some other kind of polling thread. I hate background polling threads, which was one of my primary motivations in writing CLINQ.

Now that CLINQ has some road time, I've decided to put a couple more features in it. My favorite, which is going to be in the upcoming 1.1.0.0 release (I'll be releasing it once I write some more up to date demos for the demo suite), is the notion of Continuous Aggregation. Currently, CLINQ will auto-update your collection as the result of a CLINQ query, but that's all it can do - you write a query against a collection and get a collection back. What if you want to aggregate a CLINQ results query (or any other observable collection, for that matter) into a single scalar value such as a Sum or an Average?

Currently, using v1.0 of CLINQ, the call to any of the aggregation functions will detach, or "discontinue" if you will, the connected result set. So you'll get the scalar quantity you expect, but while the CLINQ results are still updating dynamically, your scalar quantity is sitting there stagnant and you are faced with the grim possibility of having to write a background poller to update the aggregate value.

Now with v1.1, you can write code that creates continuous aggregates, as shown in some of the samples below:

ContinuousValue<int> maxAge = allCustomers.ContinuousMax<Customer>(c => c.Age);

Note that we're passing a lambda function into the continuous max method that acts as a selector. It is basically a transform that is applied to every element in the collection that converts the element into an int. In this case, I want the age of each element to be used for comparison in the Max method that is already supplied by .NET.

The reason that the lambda function is so beautiful is that you can do whatever you like. What if I want to return the sum of the cost of a bunch of order items, but I don't want the tax included and I don't have a single property for that? I can use the lambda function to strip out the tax:

ContinuousValue<decimal> totalPrice = orderMaster.ContinuousSum<Order>( 
    lineItem => lineItem.TotalCost - lineItem.Tax);

Now we're looking at being able to do things declaratively so that they are easy to maintain, easy to read, and easy to upgrade that would otherwise require the creation of methods that might be nowhere near self-documenting.

What if we want to return the average total cost of an order, but our order object doesn't have a roll-up property on it? We can actually pass a continuous aggregation around inside the selector lambda for yet another continuous aggregation:

ContinuousValue<decimal> ordersTotalCost = allCustomers.ContinuousSum<Customer>(
    customer => customer.Orders.ContinuousSum<Order>( o=> o.ItemPrice * o.ItemQuantity));

The inner continous sum for each customer order will remain continous even after this query executes. By that I mean that once I define this query, I can not only add new customers to the collection, but I can add order items to individual customers, and the updates will propogate back along the monitor chain all the way back to my aggregate value.

The only thing left to do is bind a WPF GUI to the continuously updating aggregate scalar value:

myControl.DataContext = ordersTotalCost.CurrentValue;

That's it!! Simple enough? I'm not done with the entire implementation, but the following is a list of the aggregate functions I currently have coded and tested:

  • ContinuousSum
  • ContinuousMin
  • ContinuousMax
  • ContinuousCount
  • ContinuousAverage

If you have ideas for continuous aggregates that you think I'm missing, feel free to drop by the CodePlex site for CLINQ and start up a discussion topic about it.

As usual, I will keep posting updates here and on the CLINQ CodePlex site especially when I get around to compiling the release 1.1.0.0 build.

tags:                    

links: digg this    del.icio.us    technorati    reddit

AddThis Social Bookmark Button




Tag Related Posts

WPF Control Development Unleashed

Wed 25 Mar 09 2:26 P GMT-05

Smart, Deep Property Notifications in CLINQ v2.0

Tue 07 Oct 08 1:15 P GMT-05
tags:          

Building Model Classes in C# and Cocoa

Sun 15 Jun 08 3:13 P GMT-05
tags:            

CLINQ v1.1.0.0 Released!

Fri 02 May 08 5:38 P GMT-05
tags:          

CLINQ v1 Demo - Network Message Filtering

Wed 09 Jan 08 7:47 P GMT-05
tags:        

Continuous LINQ v1.0.0.0 Released

Tue 08 Jan 08 4:53 P GMT-05

LINQ to REST - A much better name for Astoria

Tue 11 Dec 07 1:23 P GMT-05
tags:        

Unexpected and Unsafe behavior in LINQ

Wed 14 Nov 07 8:09 P GMT-05
tags:    

Building a Ledger Style for WPF Grids

Tue 21 Aug 07 3:30 P GMT-05
tags:    

Continuous LINQ - Can I write games with it?

Mon 13 Aug 07 3:09 P GMT-05
tags:        

Continuous LINQ

Mon 06 Aug 07 1:21 P GMT-05
tags:    

Dynamic, Observable LINQ Views

Tue 31 Jul 07 1:21 A GMT-05
tags:        

The dreaded language bleed-over has begun

Tue 19 Jun 07 6:23 P GMT-05
tags:        

My first "Acropolis" Application

Mon 04 Jun 07 1:40 P GMT-05
tags:      

Exploring the Delegate Design Pattern

Mon 14 May 07 6:30 P GMT-05

Installing Orcas Beta 1 - VMware Style

Mon 23 Apr 07 12:16 P GMT-05

Will Silverlight be DOA?

Mon 16 Apr 07 8:02 P GMT-05

Exploring the MVC Pattern in WPF

Tue 10 Apr 07 12:51 P GMT-05
tags:                      

Authorness

Thu 15 Mar 07 1:44 P GMT-05

WPF Bindings == WTF Bindings?

Mon 12 Mar 07 6:31 P GMT-05

On MUDs

Thu 08 Mar 07 5:00 A GMT-05
tags:                    

Visual Studio "Orcas" - March CTP is Available

Wed 28 Feb 07 12:28 P GMT-05
tags:            

Objective-C Categories vs C# 3.5 Language Extensions

Mon 26 Feb 07 1:05 P GMT-05
tags:                

Cocoa Programming vs. WPF : NIB vs XAML

Tue 20 Feb 07 2:09 P GMT-05

Cocoa Bindings vs. WPF Binding

Thu 15 Feb 07 5:41 P GMT-05
tags:                

Ulysses Agenda Makes Redmond Developer News

Wed 29 Nov 06 7:10 P GMT-05
tags:                

Is the continuous beta the new model for Vista?

Tue 21 Nov 06 8:51 P GMT-05
tags:              

Ulysses Agenda - Network Engine Test 1

Mon 09 Oct 06 2:26 A GMT-05
tags:              

ASP.NET vs Ruby on Rails : Round 2 (Agility)

Thu 05 Oct 06 11:02 A GMT-05
tags:                      

ASP.NET vs Ruby on Rails : Round 1

Wed 04 Oct 06 1:37 P GMT-05
tags:                

Ulysses Agenda : First Cut Networking Design

Thu 14 Sep 06 12:46 A GMT-05
tags:                  

First Impressions of Windows Vista RC1

Thu 07 Sep 06 1:30 P GMT-05
tags:                      

Localizing a WPF Application

Tue 22 Aug 06 11:39 A GMT-05
tags:            

WPF Slide Show and Photo Album

Fri 18 Aug 06 6:48 P GMT-05

ADO.NET Entity Framework Announced Today!

Wed 16 Aug 06 11:08 A GMT-05