Friday, October 31, 2008

If McCain wins next week...

...I'll leave the US

and I don't even live there!

Thursday, October 30, 2008

Viewing the MDX cellset with WPF

When executing an MDX query there's various bits of useful metadata that can be returned in the cellset over and above the members and dimensions you've explicitly specified in your query. This can include things like the formatted value (as specified by the cube definition) as well as other attribute values for the dimension member you're explicitly querying against.

This kind of stuff can be invaluable if you're writing your own front-end app to access OLAP data, not least because it saves a whole heap of faffing about with WITH clauses (query scoped calculated measures). Something like:

with Member (
) as TheYear,
select {
[measures].TheYear, [measures].[measure]
} on Columns,{
} on Rows from Cube
...can just become:

select {
} on Columns,{
} dimension properties member_name, member_value,
[date].[date].[date].Year on Rows
on Rows from Cube
Trouble is you'd really struggle to work this out since all that metadata is helpfully hidden from view when you execute MDX in BIDS (and MDX studio), which makes it all a bit hit-and-miss. So I wrote a little WPF app just to visualise the actual cellset returned. Pretty basic stuff - load the results into a dataset and bind it to a grid. I could fiddle with my DIMENSION PROPERTIES clause with immediate gratification.

But it took me hours to get the binding working. One of the problems is that the MDX columns have names like '[Measures].[MyThing]' and you can't just set that as the property name of your binding and expect the binding infrastructure to cope:

{Binding Path=[Measures].[SomeMeasure]}
The binding infrastructure sees the dot and tries to walk the path, with predictable results:

System.ArgumentException: Measures is neither a DataColumn nor a DataRelation for table Table

[NB: If you had a column simply named SomeMeasure this would work, due to the magic of ICustomTypeDescriptor, but that's another story]

So instead you have to use the indexer syntax on the DataRowView:

{Binding Path=['[Measures].[SomeMeasure]']}
Or (if that made you wince)

{Binding Path=Row['[Measures].[SomeMeasure]']}
But those don't work either:

System.ArgumentException: Column '"[Measures].[SomeMeasure]"' does not belong to table Table

Even whilst the same binding path works 'just fine thanks' in the debugger. It took me a long, long time to realise there's an extra set of quotes in that error message. The WPF binding syntax doesn't require quotes for string indexers:

{Binding Path=Row[[Measures].[SomeMeasure]]}
It looks so wrong but it works.

SharePoint: The final CM frontier

For a long time I thought Biztalk was the elephant in the room when it came to Configuration Management - specifically version control. I'm not talking here about Source Control, I'm talking from a deployment perspective - the 'deploy a given, atomic, integral version into production' problem.

For a traditional .net app (Winforms, ASP.Net, WPF, whatever) it's pretty much sorted. We've had source control integration in the IDE since the dawn of time, CCNet for years, and it's even easier to get CI going now that TFS 2008 supports it out of the box. That's not to say everyone actually does so, but it's there if they want it, right?

Databases are a bit harder, but there are lots of tools around that you can incorporate into your CI cycle, and now that Microsoft's in the space with VSTS for Database Pros (now included with VSTS Dev Edition) the barrier to entry has been dropped again (though it's still a pretty poor story in the SSAS space).

However for Biztalk things are not so rosy. You get source control at least, so you can practice a unified versioning / labelling scheme, but building the project doesn't give you all the artifacts you need to actually deploy into an environment. For that you've got to IDE-deploy to a dev BizTalk instance, configure and then at least export out the binding file (if not a complete MSI). There's NAnt and MSBuild tasks to do the building, but I've not seen anyone wrap up the whole end to end, so Biztalk deployments languish in the 'manual effort with concentration' department. A direct result of this is that integrating your code with biztalk orchestrations (via WS / WCF) is increasingly seen as a more manageable approach than embedding your code, thus alleviating / sidesteping many of the issues.

I thought Biztalk was the frontier of version management - that is until I started working with SharePoint.

I'd previously accepted that working with SharePoint using the Web UI was working uncontrolled, but I'd always imagined that real SharePoint developers used SharePoint Designer, checked things into source control and had established patterns for migrating content between development and production server instances. How wrong I was. Making my first tentative forays into 'how to do this properly' I was struck by the complete absence of any guidance. It appears this is most definitely not a solved problem, which Jeremy pretty much confirmed last night in his great RDN talk on the subject. There's tools out there to manage the problem, but they're pretty new on the block. The book, quite literally, hasn't been written yet.

This is clearly a pretty major failing on Microsoft's part. I appreciate that the main thrust of version-management with SharePoint is version-management of content rather than version-management of configuration, but clearly if they want developers to embrace SharePoint as a platform they're going to have to do a bit better. Time for a 'developers, developers, developers' rant perhaps?

It seems to be that the more productivity-orientated the development environment, the less effort has been put into establishing a viable CM story:

(You could substitute 'maintainability' for 'Ease of CM / CI' if you like: one tends to drive the other)

Clearly it's easier to diff / merge lines of code rather than SharePoint XML manifests (or Workflow XAMLs), but it's a complete abdication to leave these higher-level (ie non-codey) development environments quite so dramatically out the cold.

Surely there's got to be a better answer than using DiffDog for everything?

Popular Posts