Monthly Archives: December 2007

LINQPad — Query Analizer for Linq

There’s an awesome tool called LINQPad by Joseph Albahari — completely free, download here.  (“LINQPad is not an open-source product and the source code is protected by standard copyright laws.  Nonetheless, you are free to disassemble the executable to satisfy your curiosity…” says the author.) 

It’s billed as the Query Analyzer for Linq to Sql.  It does wonders for giving you a quick chance to mock up some Linq to Sql.  It is an awesome product for getting you into Linq, but it seems to fall short of it’s full potential.

What it does really well:


– Get you to think in LINQ – because you’re typing LINQ instead of SQL, you’ll get good at LINQ instead of SQL — that’s the goal now-a-days, right?  (: As soon as I get good at == instead of = and && instead of and, I’ll let you know… :)

– Quickly mock up some Linq to Sql and see what the answer is.  Discover data, harvest a quick table of results.  The results window is html, so if all you need is the table, copy-paste it into place, and say thank you.

– Samples a plenty – It’s hard to know how much I need to type in here.  Do I need a using ( MyDbDataContext db = new MyDbDataContext() ) { ?  What is the data context’s variable name?  It turns out LINQPad does all the data context creation behind the scenes, and I only need to spit out the Linq, referencing the tables by name — very nice.  I wouldn’t have figured that out on my own without the Samples tab in the bottom-left pane so eager to greet me.  Many thanks for making that so easy to stumble onto.

– The interface is very well thought out, and very elegant.  Select a db in the same place as I would in Sql Management Studio — the toolbar on the top.  Browse the databases, tables, and fields in a tree-view as I would in Sql Management Studio.  I can have multiple tabs of queries.  F5 is the shortcut to run the query.  I can look at the raw sql executed by clicking on the [SQL] button above the results pane.  Right-click on a table, and get some sample queries prebuilt for you.  Icons are natural fits.  It is very clean and elegant.  It makes me want to hire Joseph to do interface design.

There are some short-falls though that make it not as effective as it could be:


– No intelisense – the author is very specific about not liking intelisense.  I’m all for freedom of speech and the right to bear arms and legs, but I code faster with intelisense than without.  Yes, I’ve tried to build intelisense-like, type-ahead, Google Suggest type functionality before.  It is hard.  I don’t fault LINQPad for not having it — especially in a free product, but I find myself typing Linq to Sql easier in Visual Studio and then copy/paste it into LINQPad — just to get (as Rob Bagby puts it) “the intelisense love”.  And if I’m already in Visual Studio, and don’t need the bells-n-whistles, I’ll just step into the debugger and use the Linq to Sql Query Analyzer.  (Perhaps a mashup product where I can use a VS debugger visualizer to alter the linq query in place the way I can alter variables’s values during debugging?  Or embed LINQPad in a window in VS so intelisense hooks and the strongly typed data context for my project are available?)

– No renamed columns and tables – For example, when I built my .dbml file, I spent some time cleaning up where the dba of yesteryear got “creative”.  The object name is “student” where the table is “people_who_go_here”, the object’s property name is “PropertyId” where the table’s column name is “ID”.  When I do a query in LINQPad, I have to use the old name.  I’ve been splunking through the Advanced Properties in the Query menu, and it looks like there’s a way to reference the .dll my .dbml file is in, and with that, I could perhaps run my new names through LINQPad, but I haven’t figured out how to use it yet, and there’s no help file.

Summary:


For what it does, it does very well — a “Linq Query Analyzer”.  I think the documentation could be a bit better — especially in the Advanced Properties windows, but the author has done wonders to make the interface intuitive so documentation isn’t necessary.  I’d love intelisense in here, though I know how hard that would be to pull off (and Query Analyzer doesn’t have it either without Red Gate).  The interface is gorgeous, intuitive, clean, and feature rich.  Reflecting into both a database, linq code, and pulling off results in a very performant way is just phenomenal — wish I knew how he did that.  Hats off to Joseph Albahari for a great product.

Linq to Sql Query Visualizer

Scott Guthrie described an awesome Linq to Sql Query Visualizer here.  His context is Visual Studio 2008 Beta 2.  Since then, it’s gotten (almost) baked into Visual Studio 2008 RTM.  The functionality is the same, installing it is slightly different.

What is it:


During debugging, show the actual sql that will get executed from your linq query, and allow you to execute the query and see the results — all within a debugger visualizer.

How to get it:


1. Navigate to C:Program FilesMicrosoft Visual Studio 9.0Samples1033  (Modify to suite if you installed Visual Studio 2008 to a different directory.)

2. unzip CSharpSamples.zip

3. Navigate inside the unzipped content to LinqSamples/QueryVisualizer

4. Build the project if necessary.  I chose to change the solution to Release mode, since I likely won’t be debugging the visualizer.  :)

5. Copy SqlServerQueryVisualizerbinReleaseLinqToSqlQueryVisualizer.dll  to C:Users<your name here>DocumentsVisual Studio 2008Visualizers (or in XP copy it to C:Documents and Settings<your name here>My DocumentsVisual Studio 2008Visualizers)

6. Restart Visual Studio 2008

How to use it:


(graphics pillaged from Scott Gu’s original post)

1. Create a Linq to Sql query

2. Set a break point after the creation of the Linq to Sql query is formed and before the results are used — e.g. before the sql is executed.

3. Mouse over the results variable:

4. Click on the magnifying glass:

Welcome to the Linq to Sql Query Visualizer.

Note the “Original query” checkbox on the bottom-left — if you click it, you’ll see how the query is actually parameterized correctly — no sql injection here.

Note the “Execute” button on the bottom-right — if you click it, you’ll see the results that will get returned into the IEnumerable<T> results var.

In many discussions since, I’ve heard people describe TSql constructs and syntax they’ve learned by watching the queries in this window.  I can’t wait … except now that I have Linq to Sql (and Linq to Entities on the horizon), why would I want to code in TSql anymore?  :)

Rob

JavaScript namespaces without ASP.NET AJAX

In ASP.NET AJAX, you create a namespace by calling

Type.registerNamespace(‘My.Namespace.Of.Choice’);

The necessary object dictionaries are built, names resolved, everything is groovy.  But what if you can’t use that for what ever reason…

I’m working in a project that can’t use the ASP.NET AJAX Client Libraries for reasons that are irrelevant.  I want to create a namespace, so my objects don’t collide with others.  The answer turned out to be uber-simple:

var MyNamespace = MyNamespace ? MyNamespace : {};

( idea spurred from an irrelevant post at http://www.lixo.org/archives/2007/09/14/javascript-put-everything-in-a-namespace/ )

Now, I need to do that for each level:

var My = My ? My : {};

var My.Namespace = My.Namespace ? My.Namespace : {};

var My.Namespace.Of = My.Namespace.Of ? My.Namespace.Of : {};

var My.Namespace.Of.Choice = My.Namespace.Of.Choice ? My.Namespace.Of.Choice : {};

After all, a JavaScript “namespace” is just an object, and an object is just a dictionary, and a dictionary just has keys and values.  In effect a JavaScript “namespace” is just a tree of nested object instances that eventually contain my real object.  (see http://odetocode.com/Articles/473.aspx and http://robrich.org/archive/2007/09/16/Object-Oriented-JavaScript.aspx — yes, I need to blog that better)

Ok, if I want it to be compatible with ASP.NET AJAX Client Libraries, my definition needs to expand to this:

var My = My ? My : function() {

    this.__namespace = true;

    this.__typeName = “My”;

}

var My.Namespace = My.Namespace ? My.Namespace : function() {

    this.__namespace = true;

    this.__typeName = “My.Namespace”;

};

( see C:Program FilesMicrosoft ASP.NETASP.NET 2.0 AJAX Extensionsv1.0.61025MicrosoftAjaxLibrarySystem.Web.Extensions1.0.61025.0MicrosoftAjax.debug.js where it defines Type.registerNamespace around line 850 )

or using the prototype model more fully (technically, it’s just a single instance of this var, so this is way overkill):

var My = My ? My : function() {}

My.prototype.__namespace = My.prototype.__namespace ? My.prototype.__namespace : true;

My.prototype.__typeName = My.prototype.__typeName ? My.prototype.__typeName : “My”;

My.Namespace = My.Namespace ? My.Namespace : function() {}

My.Namespace.prototype.__namespace = My.Namespace.prototype.__namespace ? My.Namespace.prototype.__namespace : true;

My.Namespace.prototype.__typeName = My.Namespace.prototype.__typeName ? My.Namespace.prototype.__typeName : “My.Namespace”;

Suddenly I’m very grateful for all the work that went into the ASP.NET AJAX Client Libraries that I don’t need to do…

On a similar but completely different note, if you’re just insuring names don’t collide, a technique of wrapping your whole code block in an anonymous function works nicely ( source: http://ajaxcookbook.org/javascript-api-namespaces/ )

The technique involves putting (function(){ before your code and })(); after it.  Your whole block of code is now a function that’s executed once, then goes out of scope.  Ok, if you don’t declare your var inside the function, and you happen to name it identically to a neigboring var, I could see collisions, but likely you’re all-but safe.

Rob

Using VS 2005 and VS 2008 simultaniously

Much has been written on the fact that Visual Studio 2008 can build .net 2.0 applications, and that they can be installed side-by-side on the same machine.  This is phenomenal as it allows organizations to upgrade developer tools without forcing clients to also upgrade .net framework versions.  Very nice.

However, what isn’t as fully documented is using Visual Studio 2008 and Visual Studio 2005 together on a development team.  For example, Sally Slickster is an early adopter, downloaded the VS 2008 iso from MSDN 8 minutes after Scott Guthrie posted the RTM news.  She’d like to use it for all development work from now on.  Harry Hard-head, on the other hand, just figured out where all the settings are in VS 2005, and installed VS 2005 SP 1 under great duress.  No way will he use VS 2008 until at least SP 1.  They’re both working on the same .net 2.0 project.

When converting a VS 2005 project to VS 2008, and leaving it to target .net 2.0, it only changes 2 sets of files: the solution file (*.sln) and the project file(s) (*.csproj).  Ok, technically, as VS 2008 developers do things, it’ll replace some comments with new version information.  The header at the top of .designer.cs files now reads version 2.0.50727.1433 for example.  Since these files are rebuilt any time the designer sneezes, I’ll ignore them.

The .sln files used by VS 2008 and VS 2005 are similar, but not compatible.  (So says my very un-scientific testing.)  Yes, get annoyed, get indignant, run the VS 2008 conversion wizard, leave the projects in .net 2.0 mode, then check in the second .sln file in source control.  I hate it too, but it could be worse.

The .csproj files are a different story.  During the VS 2008 conversion wizard, many new nodes and attributes are added to each project.  I didn’t find anything removed, just new stuff added.  With these in place, VS 2005 pulls up a “This project has been modified outside the designer” security warning box the first time the project is re-opened.  UAC has trained me to ignore these dialogs and just push OK.  Closing and reopening VS 2005 seems to not bring up the security dialog a second time.

The major headache with the .csproj files is with Web Application Projects.  This line is changed:

<Import Project=”$(MSBuildExtensionsPath)MicrosoftVisualStudiov8.0WebApplicationsMicrosoft.WebApplication.targets”

/>

it becomes:

<Import Project=”$(MSBuildExtensionsPath)MicrosoftVisualStudiov9.0WebApplicationsMicrosoft.WebApplication.targets”

/>

Note the ‘v8.0’ becomes a ‘v9.0’.

Well, now VS 2008 is happy, but VS 2005 users can’t build because C:Program FilesMSBuildMicrosoftVisualStudiov9.0 doesn’t exist on their machines.

Adam Salvo suggests just copying this directory from a machine with VS 2008 on it to all the machines without it.  It’s a whopping 900k, so who cares.  Perhaps a carefully named shortcut could do the job as well.

Steven Harman suggests replacing the offending line in the .csproj file with these lines:

<Import Project=”$(MSBuildExtensionsPath)MicrosoftVisualStudiov8.0WebApplicationsMicrosoft.WebApplication.targets” Condition=”‘$(Solutions.VSVersion)’ == ‘8.0’”/>

<Import Project=”$(MSBuildExtensionsPath)MicrosoftVisualStudiov9.0WebApplicationsMicrosoft.WebApplication.targets” Condition=”‘$(Solutions.VSVersion)’ == ‘9.0’” />

Basically, tell it to use what ever works best.  Very nice.  Very clean.  Very self-contained.  Yes.

Perhaps in time, everyone will move to VS 2008 and this problem will just disappear.  In the mean time, now Sally and Harry are happy, and you know what happens when Harry met Sally…

Rob

TortoiseSVN committed a file like myapp.pdb or Thumbs.db. Now what?

A very specific rule for using source control is to avoid putting temporary files, user files, or compiled content into the repository.  These files change far too frequently and offer little value to the versioning and historical process.  More than anything, they’ll just make the repository excessively large and make everyone update their checked out copies more.  However, keeping temporary files out of SVN using TortoiseSVN isn’t a perfect science.

TortoiseSVN will suck in everything in the folder, including hidden files and folders.  Windows hides the Thumbs.db file — a cache of image thumbnails in the folder.  To see this file, open the folder in Windows Explorer, choose Tools menu -> Folder Options -> View tab -> Show hidden files and folders.  Now that you can see it in Windows Explorer, you can delete it from SVN in the standard way.  Standard caveat though: it deletes it from now on in the checked out trunk, it doesn’t delete the history of the file being there, and by deleting it, you won’t make the repository smaller.

A more industrial-strength way to avoid files like this from entering the repository is to adjust TortoiseSVN’s settings.  From Windows Explorer, right-click, choose TortoiseSVN -> Settings.  In the General section, there’s a “Global ignore pattern”.  Mine currently looks like this:

bin obj CVS .cvsignore *.user *.suo Debug Release *.pdb test.*

This is just a space-delimited list of file patterns to ignore.  You can add Thumbs.db here or any other file mask that you’d like Tortoise to ignore when checking in files.  (Since I disabled creation of Thumbs.db on my system, I don’t yet have it in the list.  You also may not need the CVS patterns if you have no legacy CVS content hanging around.) The lynch pin here though is this is a per-svn-client setting, not per-project or per-folder.  If someone else in the team checks out the source, builds it, and checks it in, if they weren’t paying attention, they’ll likely push these unwanted files into the repository.  (My solution to that is to hand the global ignore pattern list to everyone in the team.)

If you’d like a server-side solution, with the files not checked in (or previously removed, committed, and rebuilt), you can right-click on them in Windows Explorer, choose TortoiseSVN, and Ignore.  You can also do this by right-clicking on them in the Tortoise’s commit screen.  The up-side is this is server-side, so it applies to all users of this file or folder.  The down-side is this is per-file.  So, each new project, new solution, or new directory added to the repository needs some TLC right out of the gate to insure it doesn’t commit these files into the repository.

Which of these two is the best strategy for ignoring these files and folders?  The first is great for many folders and few people or people that don’t change much.  The latter is good for many people and few folders or for teams that have high turnover.  But as always, your mileage may vary, and your comfort with each paradigm may temper your success.

Rob