StreamInsight: Obscure LINQ error - The field 'Key' of type 'IKey`1' either contains a nested member, or is a type that is not supported as event type field
This is a pretty obscure one, and a nice short snippet of a blog post. I ran into this error yesterday while building out some StreamInsight applications for real time web analytics, and was very briefly stumped. Let’s have a quick peek at how I ran into it.
Starting with a working query, I needed a different pivot/aggregation on the same data stream. My working query was:
Code Snippet
- // Create the "average" quality metrics for each video from raw video quality
- // metrics (i.e. not quantized)
- var videoQualityByVideo = from e in this.videoQualityStream
- group e by new { e.ApplicationId, e.VideoId } into videoGroups
- from win in videoGroups.TumblingWindow(defaultWindowSize,
- HoppingWindowOutputPolicy.ClipToWindowEnd)
- select new
- {
- ApplicationId = videoGroups.Key.ApplicationId,
- VideoId = videoGroups.Key.VideoId,
- AverageBitrate = win.Avg(e => e.BitRate)
- };
Pretty basic stuff – now, I wanted to group by another field (in this case a field called EdgeServerName). So, I copy and paste, change the grouping field name and away we go:
Code Snippet
- // Create the "average" quality metrics for each video from raw video quality
- // metrics (i.e. not quantized)
- var videoQualityByEdgeServer = from e in this.videoQualityStream
- group e by new { e.EdgeServerName } into videoGroups
- from win in videoGroups.TumblingWindow(defaultWindowSize,
- HoppingWindowOutputPolicy.ClipToWindowEnd)
- select new
- {
- EdgeServerName = videoGroups.Key,
- AverageBitrate = win.Avg(e => e.BitRate)
- };
Should be fine – right? Those of you familiar with LINQ are probably already laughing at the minor syntax mistake I made, but for the rest of us here’s what happened when I tried to run the query:
|
Ouch. What did I do wrong? A composite group key must have more than one field!
Right | Wrong! | Right |
Code Snippet
|
Code Snippet
|
Code Snippet
|
Removing the new {} syntax for a single grouping field worked perfectly. Another bit of LINQ learned!
Code Snippet
- // Create the "average" quality metrics for each video from raw video quality
- // metrics (i.e. not quantized)
- var videoQualityByEdgeServer = from e in this.videoQualityStream
- group e by e.EdgeServerName into videoGroups
- from win in videoGroups.TumblingWindow(defaultWindowSize,
- HoppingWindowOutputPolicy.ClipToWindowEnd)
- select new
- {
- EdgeServerName = videoGroups.Key,
- AverageBitrate = win.Avg(e => e.BitRate)
- };
But wait… there’s more! Through the course of the same project, I also ran into another way to throw this error, in a slightly different fashion.
Code Snippet
- var videoQualityByEdgeServer = from e in this.videoQualityStream
- group e by new { e.ApplicationId, e.EdgeServerName } into edgeGroups
- from win in edgeGroups.TumblingWindow(videoQualityEventWindowSize, windowAlignment,
- HoppingWindowOutputPolicy.ClipToWindowEnd)
- select new
- {
- ApplicationId = edgeGroups.Key,
- EdgeServerName = edgeGroups.Key.EdgeServerName,
- // Buffering Milliseconds -> Seconds
- // Divide by sampling frequency seconds
- // Multiply by 100 (1 / 1000 * 100 = 1 / 10)
- AvgBitrate = win.Avg(e => e.BitRate)
- };
If you have a composite key, and don’t use the individual properties of the grouping key, the error is thrown. Easy in retrospect, right?