LINQPad: More control over your queries
Tags: linqpad, dotnet, csharp, productivity
Published: 2019-09-21 12:51:46

# Keep exploring

Following my [previous post](https://dev.to/tanathos/linqpad-why-i-love-it-and-why-you-should-too-5927) of this serie, I'll keep exploring the tool, to show you some useful trick you can use to get a better control of the query.

If you're an experienced LINQPad user a lot of this stuff will look trivial, but I actually used it for years without knowing them, and I think some of you will appreciate a kickstart.

# Control the Dump

As you already noticed the result of the Dump() extension is varying from type to type. Simple types and strings, for example, are just dumped as HTML strings on the output panel.

![](https://thepracticaldev.s3.amazonaws.com/i/ax0wurfzvyqsbnmq03sb.png)

Objects are dumped as HTML table with their properties exploded on rows:

![](https://thepracticaldev.s3.amazonaws.com/i/c0fifpkdi143i6zux2bi.png)

While arrays, lists and other enumerable types are rendered as tables in which properties are exploded in columns:

![](https://thepracticaldev.s3.amazonaws.com/i/lp1zkmrc345u4liwsa1b.png)

The Dump() extension is automatically searching for public properties, recursively, nesting the results where is needed and rendering them is its standard way.

But if you look at the overloads of the method you'll see 5 parameters:
- description
- depth
- toDataGrid
- exclude
- alpha

Writing something like:

```csharp
DateTime.Now.Dump("Current date:");
```
Will use the *description* param, nesting the result under a label, useful if your query is outputting a lot of variables.

With the *depth* parameter you can control how much deep the Dump() is exploding the object on the first render. By default is 5, that means the Dump is preparing 5 levels of nested HTML tables upfront, and it can be a little too much, especially on large and complex objects (you will notice that the execution of the query will slow considerably if you try to render hundreds of results together). Setting the depth to a lower value will speed up the first render, and you'll still be able to manually explode the collapsed properties on the output panel just clicking on them.

Try for example:
```csharp
System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures).Dump(1);
```

You'll notice a faster rendering, as this collection is quite big.

With the *toDataGrid* setted to true the output panel will switch to a WPF control instead of the standard HTML, while *exclude* allows you to omit from the rendering specific properties:
```csharp
System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures).Dump(toDataGrid: true, exclude: "Parent");
```

Finally, the *alpha* params setted to true changes the order of appearence of the properties. By default LINQPad write them as they appear in the class, with this you'll see them alphabetically ordered.

# Implementing ToDump()

You may need to specify a custom way to show data of specific classes, for example explicitating the properties to show or even the HTML format to use.

The fastest way is implementing a ToDump() method in the class, so assuming the class is defined in the query itself, you can write:
```csharp
class User
{
	public string FirstName { get; set; }

	public string LastName { get; set; }

	object ToDump()
	{
		return new {
			FirstName = this.FirstName,
			LastName = Util.WithStyle(this.LastName, "color:green")
		};
	}
}
```

In this case ToDump() is returning an anonymous object with the same properties, but LastName will be rendered in green color (notice the use of `Util`, we'll talk more about later).

Implementing this kind of method in your domain model is not optimal (in this case impossible, `Util` is defined only in LINQPad queries), so an alternative would be to use a static method in the "My Extensions" query.
"My Extensions" is a special query you'll find in My Queries tab, that's always included during the execution of the other queries, so whatever you link or define there will be available everywhere.

Still not optimal: you'll have to move your `User` class in My Extensions (or reference there the assembly which contains the class). That, as said, will import the class in EVERY other query you will run.

In the end the best approach is working with reflection and `dynamic` keyword.

```csharp
public static object ToDump(object input)
{
	if (input.GetType().FullName == "User") // e.g. "MyApp.DataModel.User"
	{
		dynamic output = input;
		
		return new
		{
			FirstName = output.FirstName,
			LastName = Util.WithStyle(output.LastName, "color:green")
		};
	}

	return input;
}
```

Another good approach, assuming you're producing your own NuGet packages, is to include in them a set of LINQPad example to be imported in your queries, as I'll show in future posts.

# DumpContainer examples

A simple `.Dump()` invocation can be limiting in some scenario: each one is going to create a new dumped output row, in a sequence, without the ability to change the actual dumped result during the execution of the query. But if you need to show a progress or an updating information in general is not the good thing to use.

`DumpContainer` is going to help you.

As the name suggests is a sort of container for dynamically updated contents, you Dump() it once and update its `Content` as you need during the lifetime of the query:

```csharp
void Main()
{
	DumpContainer dc = new DumpContainer();
	dc.Content = "Starting the application...";
	dc.Dump();

	Thread.Sleep(500);

	for (int i = 1; i <= 10; i++)
	{
		dc.Content = $"{i}/10 - Processing...";
		Thread.Sleep(200);
	}
	
	dc.Content = "Completed!";
}
```

If you just need a progress bar to be shown you can use, guess what, `Util.ProgressBar`. 

As I said before, each LINQPad query's referencing LINQPad.Util namespace, an utility belt full of useful tools to interact with LINQPad itself, and ProgressBar is a class to work with simple but effective HTML progress bars.

We can replace the previous code with something like:

```csharp
void Main()
{
	Util.ProgressBar pb = new LINQPad.Util.ProgressBar();
	pb.Caption = "Progress";
	pb.Dump();

	for (double i = 1; i <= 10; i++)
	{
		pb.Fraction = i/10;
		Thread.Sleep(200);
	}
}
```

In this case you can interact with the `Fraction` or `Percent` property to advance the bar.

![Full progress bar](https://thepracticaldev.s3.amazonaws.com/i/7f1d8wgq177ytjb2c94y.png)


# Manage input for interactive queries

In some scenario it can be useful to just not hardcode everything, but to ask for user input(s), in the same way you'll do with a console application.

Again you can access the Util namespace ad use the ReadLine() method. This will prompt an input box at the bottom of LINQPad window, its input can be assigned to a string variable and be used in the execution code:

![Input example](https://thepracticaldev.s3.amazonaws.com/i/ind38tim9ppmode29g1d.png)

# Exploring the Util.*

Explore the Util namespace! Is really full of useful stuff that'll help you pushing your queries to the next level.

Some examples:

- .Cmd() : Will execute any system command
- .Dif() : A graphical comparer for objects, allows you to easily show differences between two given inputs
- .KeepRunning() : creates a cycle to keep the query alive, useful when working with secondary threads
- .CurrentQuery : is the object representing the current query, allows you to access the raw code and assembly references

# Conclusions

LINQPad is really an amazing piece of software, knowing it well is going to improve by a factor of ten your productivity in the .NET ecosystem.

I'm going to write at least another post about it in the future, because there are still interesting stuff to talk about.

Stay tuned!