LINQPad Tips and Tricks - Part 2


This is my second LINQPad Tips and Tricks post. If you haven't read my first post, I'd definitely recommended reading that one first, and then coming back to this one ...

Wow, that was quick! Okay, so without further ado, onto the tips! ...

Create Symbolic Links in your Query folder

Unfortunately, you can only specify a single root folder as your My Scripts folder (ie. the folder that appears in the 'My Queries' panel). Whilst this folder can have subdirectories so you can still categorize your scripts - we actually quite often want our scripts with our various projects so it goes into that project's source control.

The best way I've found to get around this problem is to create symbolic links. You can do this easily by opening the command line, navigating to the LINQPad scripts folder, which will be something like C:\Users\Dan\Documents\LINQPad Queries, unless you've changed it (or your name isn't Dan!), then type the following command ...

mklink /j <folder-name-to-appear-in-linqpad> <path-to-real-folder>

So for example ...

mklink /j  MyProject c:\code\myproject\Scripts

Then you'll have a MyProject folder in your LINQPad 'My Queries' panel. You can do this for all your projects, meaning quick access to your scripts, whilst keeping them where they belong - source controlled with the project itself.

Editing data inline via the grid view

This is probably one most LINQPad users already know, but definitely worth mentioning. Using the query window's toolbar buttons, you can switch between the normal rich text output, or the datagrid view. You can also use the keyboard shortcuts ctrl-shift-t and ctrl-shift-g to switch between them.

One you dump the results to a grid, depending on what you're outputting, you should see a hyperlink above the grid that says Edit Data. Clicking on this will let you edit your data inline in the datagrid itself.

Global Extension Methods

Another one that I'm sure most LINQPad users already know, but again worth pointing out. In your My Queries pane, you'll see a query called My Extensions. In this file, you can add custom extension methods that will be available in all of your queries.

Remember Dump() returns the dump object

Because the Dump() method returns the object that you're dumping, you can combine a variable assignment and a dump ...

var product = Products.FirstOrDefault(x => x.ID == 123).Dump();

Clone a Query Window

Sometimes it's useful to clone an existing query window. This might be because you want to make temporary changes without accidentally saving changes to an existing file. Or a use-case I've been using it for recently is for load testing. Quickly cloning a load testing script lots of times and running it. You can clone the current query window by pressing ctrl-shift-c. Or choose it from the menus, but hey, keyboard shortcuts are faster! This not only clones the script itself, but also any references (eg. Nuget packages).

Run Stored Procedures just like they were methods

This one is from Dominic Rawle on Twitter. If your database has Stored Procedures, then you can literally just call them like they were .NET methods!

Disable caching within the same query execution

LINQPad actually caches database requests within the same execution. Separate executions are never cached - but you'll get cached results if you dump twice within the same execution. This is because of LINQ2SQL's 'Object Tracking'. If you do not want this, you can disable it with ObjectTrackingEnabled = false;.

Stackoverflow reference

Attaching Visual Studio to a LINQPad Query

I know I mentioned this in my last post, but what I didn't mention was that in the bottom-right hand corner of the LINQPad window, you have a process id. LINQPad tried to reuse the last process for a given script - so if you run the script once, then you'll see the process id, making it very easy to attach Visual Studio to. Once attached, just run your LINQPad script again. This is especially useful if your script is referencing one of your own .NET assemblies, and you want to debug the assembly itself.

InternalsVisibleTo advanced setting

Occasionally it can be useful to allow LINQPad to access internals in your assembly. Whilst the thought of this might make the purists lose sleep - sometimes it can be really useful! You can easily do this by adding [InternalsVisibleTo("LINQPadQuery")] to your project's AssemblyInfo.cs file. You'll then need to enable this in LINQPad via the Allow LINQPad to access internal types of other assemblies advanced setting.

Customize Dump with ToDump

If you want to customize what gets dumped for a given object type, you can add a ToDump method to the object and return an anonymous object with the properties that should appear in the dump output. For example ...

public class Customer
{ 
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public DateTime BirthDate { get; set; }

   // The ToDump method can be private, so it doesn't pollute your type's public interface.
   object ToDump() => new { FirstName, LastName };
}

The snippet above has been shamelessly pinched from the LINQPad documentation page about this, and you can read more about it here.

Adding Winforms or WPF controls

The output of LINQPad is very extendible. You can even render Winforms and WPF controls! Rather than repeating what's already in the docs, I'm going to point you both at the Custom Visualizers page, and also this Tweet with a nice animated gif ...

OnDemand

Sometimes if your results return a lot of data, you don't always need to see all of the data straight away. The built-in Util.OnDemandmethod allows you to render a hyperlink which then does something once clicked on. For example ...

Util.OnDemand("Some Expensive Query", () => MyExpensiveQuery())

This will output a hyperlink which the user can click to execute the query. The hyperlink will then be replaced with the output once clicked.

Summary

So hopefully this second post has added a few more tricks to your LINQPad toolbelt! As I mentioned in my last post, if you have any other nuggets I haven't included, then please share in the comments below!

Happy LINQPadding! ...