LINQPadを使ってみよう

  • 78
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

LINQPadとは

無償のスタンドアロンアプリケーションであり(有償版もある)Joseph Albahari氏によって作成されました
名前にあるようにLINQの実行はもちろん、.NETのコードであれば、すぐに実行可能な環境です
サイトはこちら
http://www.linqpad.net/

まずは動かしてみる

ちょっとしたコードを確認したい場合に、LINQPadは以下のようにすぐに試す事が可能です
LINQPad1.png

各画面の構成は以下のようになっています
LINQPad.png

Editon

2015/04/03 時点では、Free、Pro、Developer、Premium の4種類のEditionがあります
Edition毎に使える機能の概要

今までのPremiumが今回のDeveloperになったイメージです
後述しますが、今回追加されたdebugger機能が使えるのが、新しいPremiumのみとなってます

Dumpメソッドである程度何でも確認できるのですが、いろいろ試しているとdebugger欲しい!ってなるので、買うならPremium Editionが個人的にはおすすめです

設定

各種設定可能な項目について記載します

Preferences

[Edit]メニューの[Preferences]を選択することで表示されます
ここで、LINQPad全体に対する共通的な設定を行う事が可能です
Preferences

各タブでの設定可能項目の概要

  • Editor:フォント、バックグラウンド、行の表示など
  • Query:デフォルトLanguage(C# Statetment,C# Programなど)、コンパイル時のクエリ最適化
  • Results:実行結果の表示領域[Results]に対する設定
  • Folders:各ファイル(クエリ、スニペット、拡張機能)の保存フォルダを設定
  • Web proxy:LINQPadが外部通信するために使用するProxyを設定(自動更新や、Samplesファイルのダウンロード時に使用)
  • Advanced:各種設定(フラグをON、OFFするようなものがほとんど)

接続文字列の設定

画面左上の[Add connection]押下にて、接続文字列の追加が可能です

[Add connection]押下すると、まず以下の画面が表示されます
Choose Data Context

LINQ to SQLがデフォルトで選択されていますが、他のものを選択することも可能です

LINQ to SQLを選択した場合は、以下のような画面が表示されます(違うものを選択した場合、設定項目が異なるので画面も変わります)
LINQPad Connection

ここに必要な項目を入力し、[OK]を選択すると左上の一覧に追加され、右上の[Connection]のリストから選択可能となります

dllの参照、namespaceの設定

[F4]押下にて、Query Properties画面を表示します

※[Query Properties画面]は、[Query]メニューの[Query Properties]からも表示可能です

Additional Referencesタブ

参照するdllを設定する画面です
QueryProperties - Addtional References.png

  • Add... 一覧の中から参照するdllを選択します
  • Browse... ファイルから参照するdllを選択します。自分で作成したプロジェクトのdllも参照可能です
  • Add NuGet... Nugetから取得します(Free版では、サンプルとして用意されているものしか選択できません。Premium Editionで一般に公開されているものを選択可能となります)

左下の[Set as default for new queries]をクリックすると、現在設定している内容をデフォルト設定にします
次回以降新規で作成するファイルは、この設定をデフォルト設定として使用します

自分が作成したプロジェクトのdllも参照可能なので、publicメソッドをLINQPadから実行することが出来るので、簡単な動作確認をLINQPad上からも行えます

Additional Namespace Importsタブ

usingするnamespaceを設定

QueryProperties - Addtional Namespace Imports.png

usingと[;(セミコロン)]は不要です。以下のようにnamespaceを入力するだけでよいです

System
System.Collections.Generic
System.Linq

右上の[Pick from assemblies]を選択すると、[Additional Referencesタブ]で参照したdllの中から、設定しておきたいnamespaceを選択することが可能です

アプリケーションの構成(app.config相当)

linqpad.configを作成し、LINQPad.exeと同じフォルダにおく事で設定可能です
※linqpad.exe.configは、LINQPadのGUI用なので注意が必要です

記述内容は、app.configと同じです
以下は、LINQPad.configのサンプルです

LINQPad.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
  </configSections>

  <appSettings>
    <add key="Application Name" value="MyApplication" />
    <add key="Application Version" value="1.0.0.0" />
  </appSettings>

  <connectionStrings>
    <add name="MyDB" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=test;User ID=User;Password=Pass;Min Pool Size=2"/>
  </connectionStrings>
</configuration>

機能紹介

Language

2014/11/14時点では、以下の言語で処理を記述することが可能です

  • C# Expression
  • C# Statement(s)
  • C# Program
  • VB Expression
  • VB Statement(s)
  • VB Program
  • SQL
  • ESQL
  • F# Expression
  • F# Program

Expression:式のみ
Statement:行
Program:通常の処理(クラスなども記述可能)
という違いとなっています

デフォルトは C# Expressionが選択されているため、式しか記述出来ません
複数行の処理を記述する場合は、
画面上部の真ん中あたりの[Language]にて、
C# Statement(s)
C# Program
を選択します

Dumpメソッド

まずは、Dumpメソッドを使ってみましょう
Dumpは、<T>に対する拡張メソッドとして定義されています
なので、基本的にはなんでもDumpを実行することが可能です

このDumpを実行すると、現在のオブジェクトを、いい感じに[Results]の箇所に表示してくれます

var hoge = new { Hoge = 1, Fuga = 2};
hoge.Dump();

Dump Sample

また、Dumpは自身のオブジェクトを返すので、上記の例であれば、以下のように記述することも可能です
var hoge = new { Hoge = 1, Fuga = 2}.Dump();

Dumpを使えば、初めてLINQを触るときなどに理解しづらいLINQ関連のメソッドの実行状況も確認しやすいです

string[] Words = new string[] {"   KOOKABURRA", "Frogmouth", "kingfisher   ", "loon", "merganser"};
Words
  .Dump("ORIGINAL:")
  .Select(word => word.Trim())
  .Dump("TRIMMED:")
  .Select(word => word.ToLower())
  .Dump("LOWERCASE:")
  .Where(word => word.StartsWith("k"))
  .Dump("FILTERED to 'K':")
  .OrderBy(word => word)
  .Dump("SORTED:");

また、System.Windows.Forms.DataVisualization.Charting 名前空間を使って、Chart(グラフ)のDumpも可能です

chartDump
//以下のdllの参照と、namespaceのimportsを設定済みです
//System.Windows.dll
//System.Windows.Forms.dll
//System.Windows.Forms.DataVisualization.dll
//using System.Windows.Forms.DataVisualization.Charting

void Main()
{
    var chart = new Chart();
    chart.ChartAreas.Add(new ChartArea());
    var series = new Series { ChartType = SeriesChartType.Column };
    foreach (var item in Enumerable.Range (1, 10))
    {
        var x = item;
        var y = item;
        var index = series.Points.AddXY(x, y);
    }
    chart.Series.Add(series);
    chart.Dump("Title");
}

Chart Sample

このようにとても便利なので、何かの結果を見たい時は、Dump使い倒しましょう

ちなみにDumpには、6つのオーバーロードがありますが、以下2つの引数の組み合わせとなります
string descripton // [Results]に表示されるタイトル
int? depth // [Results]に表示するオブジェクトの展開を行う階層(デフォルトは全て展開済み)

デバッグ(LINQPad単体でのdebugger機能は、Premium Editionのみ)

2015/04/03 追記
v4.55(2015/03/03)から、debugger機能が追加されました!(Premium Editionのみ)
※debugger機能追加に関しては、こちらのスレッドでやりとりされていたようです

これによりbreakポイントの設定や、ローカル変数を一覧にて確認可能となります

debuggerサンプル

上に虫っぽい形のアイコンが追加されていますが、
未処理例外発生時にBreakする
Exception発生時にBreakする
を設定する項目となります

Debugger.Launch()

複雑なデバッグを行いたい場合は、Debugger.Launch();にて、VisualStudioをデバッガーとして起動することが可能です
その際とめたい箇所でDebugger.Break();も記述しておかないとそのまま処理が流れてしまうので、必要な個所で止めるようにしておきましょう

// LanguageにC# Programを選択
void Main()
{
    Debugger.Launch();

    var a = 1;

    // Breakを実行しておかないと、処理がそのまま流れてしまう
    Debugger.Break();

    a = a + 10;
}

Utilクラス

LINQPad自体に定義されているクラスです
LINQPadを利用する上で便利な機能が用意されています
以下に、Sampleを記載しておきますが、ここで紹介した以外にも沢山のメソッドがあるのでぜひ試してみてください
※一部コメントアウトしているので、必要に応じて有効にして確認してみください

void Main()
{
    "".Dump("表示関連");

    "".Dump("Progressbar表示");
    var bar = new Util.ProgressBar("Progressbar表示");
    bar.Dump();
    foreach (var element in Enumerable.Range(1, 100))
    {
        bar.Percent = element;
        System.Threading.Thread.Sleep(50);
    };
    // Progressbar表示の部分のみ実行できるように「;」を入れてます


    Util.Metatext("Metatext").Dump("Metatext 表示を(緑+イタリック)にする");

    Util.Highlight(new { a = 1 , b = 2, c = 3}).Dump("Highlight Dumpメソッドでの出力結果をハイライト表示(文字列以外は効果がない?使い方を間違えてるだけかも)");

    var a = new DummyData(){ Name = "1", Id = 1 };
    var b = new DummyData(){ Name = "2", Id = 2 };
    Util.VerticalRun(Util.Highlight(a), b).Dump("VerticalRun 複数のデータを垂直方向にまとめてDumpする(クラスはHighlight効かない)");
    Util.VerticalRun(Util.Highlight("abc"), "abc").Dump();

    Util.WordRun(true, Util.Highlight(a), b).Dump("WordRun 複数のデータを垂直方向にまとめてDumpする、第1引数は表示領域がたりなかった場合に折り返すかどうかのフラグ。(クラスの場合は横にならない、Highlight効かない)");
    Util.WordRun(true, Util.Highlight("abc"), "abc").Dump();
    Util.WordRun(false, Enumerable.Range (0, 100)).Dump();

    Util.RawHtml(Util.ToHtmlString(
            Enumerable.Range (0, 10).Select (e => new { e, a = e * e, b = e * 2 })
        )).Dump("RawHtml html形式で表示(ToHtmlStringと組み合わせて使ってみた)");


    "".Dump("文字列整形");
    Util.ToCsvString
        (
            Enumerable.Range (0, 10).Select (e => new { e, a = e * e, b = e * 2 }),
            new string[]{"e", "a"}
        ).Dump("ToCsvString 渡されたオブジェクトをcsv区切りの文字列として返す。第2引数で出力する列の選択が可能");
    "".Dump("WriteCsv ファイルへCSV形式で書き込み。ToCsvStringに書き込み先のファイルパスが増えたような感じのインタフェース");
    //Util.WriteCsv

    Util.ToHtmlString(Enumerable.Range (0, 10).Select (e => new { e, a = e * e, b = e * 2 })).Dump();


    "".Dump("LINQPad自体の情報取得");
    Util.GetWebProxy().Dump();
    Util.GetMyQueries().Dump("GetMyQueries My QueriesフォルダにあるLINQファイルの一覧を表示");
    //Util.GetSamples().Dump("GetSamples SamplesフォルダにあるLINQファイルの一覧を表示");
    //Util.GetSamplesFolder().Dump("GetSamplesFolder Smapleファイルの格納先フォルダのパスを取得");
    Util.CurrentQueryPath.Dump("CurrentQueryPath 現在のファイルのパスを返します。未保存の場合は、nullが返されます");

    "".Dump("その他");
    var result = Util.Cmd("ping localhost").Dump("Cmd dosコマンドを実行することが可能 実行結果を戻り値として受け取る事も可能");

    Util.CurrentDataContext.Dump("CurrentDataContext 現在のDataContextが取得可能。右上のConnection未選択時はnullを返す)");

    var sw = Stopwatch.StartNew();
    Util.OnDemand("クリックしたら実行する", () => sw)
        .Dump("OnDemand クリックされた時に第2引数で指定されたFuncを実行し、Dumpする。とある処理の途中経過のデータ保持とかにも使えそう");


    "".Dump("Run 指定したlinqファイルを実行できます。戻り値の形式は第2引数 formatで指定。実行したlinqファイル内でdumpしていた内容が返ってきます");
    //var run = Util.Run(@"", QueryResultFormat.Html);
    //run.Dump();

    "".Dump("ReadLine Console.ReadLine()にタイトルが設定できる");
    //Util.ReadLine("Console.ReadLine()にタイトルが設定できる").Dump("ReadLine Console.ReadLine()にタイトルが設定できる");
    //Console.ReadLine().Dump("単純なConsole.ReadLineはTitleタイトル設定できない");

    "".Dump("DisplayWebPage Webページの表示が可能");
    //Util.DisplayWebPage("http://google.com", "google");
}

// Define other methods and classes here
public class DummyData
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Value { get; set; }
}

※Intellisense が使えるのはPro Edition以上なので、UtilクラスにどういったメソッドがあるかFreeだとパッとわかりません
 明示的に定義されているドキュメントも見当たらなかったので、Freeでどういったメソッドがあるか確認する場合は、
 ILSpyなどを使用して確認してみてください

Hyperlinqクラス

単純なリンクだったり、処理だったり、新しいlinqファイルを作ったりいろいろできます

HyperlinqSample
void Main()
{
    new Hyperlinq("http://google.com").Dump();
    new Hyperlinq(
            () => Enumerable.Range (0, 10).Select (e => e).Dump(),
            "test",
            true
        ).Dump();

    new Hyperlinq(QueryLanguage.Statements, "var a = 1;a.Dump();", "test").Dump();
}

My Extensions

自身の実行環境で常に参照したい処理を入れておく事が可能です
画面左下の[My Queries]タブの一番下に表示されている[My Extensions]を選択します

My Extensions

コメントに記載されている通りですが、それぞれのブロックに以下の内容を記述可能です

MyExtensionsクラスに、独自のメソッドを記述します(拡張メソッドや、staticメソッドなど)

Main() には、上記に対するテストコードを記述します(特になくても問題はないです)

両方の範囲外の箇所には、non-static classesやenumsなどを定義可能です

MyExtensionsSample
void Main()
{
    // Write code to test your extensions here. Press F5 to compile and run.

    // 拡張メソッドの確認
    var unixTime = 1416904530L;
    var date = new DateTime(2014, 11, 25, 17, 35, 30);
    date.ToUnixTime().Dump("DateTime To UnixTime");
    unixTime.FromUnixTime().Dump("UnixTime To DateTime");

    (date == unixTime.FromUnixTime()).Dump("date == unixTime.FromUnixTime()");
    (date.ToUnixTime() == unixTime).Dump("date.ToUnixTime() == unixTime");

    // 静的メソッドの確認
    MyExtensions.GetDummyDatas(10).Dump();
}

public static class MyExtensions
{
    // Write custom extension methods here. They will be available to all queries.

    private readonly static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    public static long ToUnixTime(this DateTime dateTime)
    {
        dateTime = dateTime.ToUniversalTime();
        return (long)dateTime.Subtract(UnixEpoch).TotalSeconds;
    }

    public static DateTime FromUnixTime(this long unixTime)
    {
        return UnixEpoch.AddSeconds(unixTime).ToLocalTime();
    }

    public static IEnumerable<DummyData> GetDummyDatas(int dataCount)
    {
        return Enumerable.Range(0, dataCount).Select(x => new DummyData { Id = x, Name = string.Format("Name{0}", x), Value = x * 2 });
    }
}

// You can also define non-static classes, enums, etc.
public class DummyData
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Value { get; set; }
}

参照していない型名の解決(Pro Edition以上)

LINQPad上でまだ参照していない型名を入力した場合、自動で解決してくれる機能です
まだ何も参照していない状態で、protecteddataを入力した後に文字列の後ろのほうにマウスカーソルをあてると、以下のようなメニューが表示されます
参照していない型名の解決

using System.Security.Cryptography(in System.Security.dll)を選択すると、dllの参照と、System.Security.Cryptographyをusingしてくれます
System.Security.Cryptography.ProtectedData(in System.Security.dll)を選択すると、dllの参照と、System.Security.Cryptography.ProtectedDataというようにフルパスにしてくれます(usingはしません)

自動で解決可能なものは、.Net Framework標準の型か、自分で参照させたアセンブリ内に含まれるものです

DBへの処理(GUIでの編集は、Premium Editionのみ)

設定した接続を使ってDBに対して処理を行う事が可能です

DB Edit

LINQ To SQLで作成していれば、そのままWhere条件などによる絞りこみも可能です
Categories.Where(x => x.CategoryID == 3).Take(100)

※テストデータは、Smaplesの中の
LINQPad 5 minute induction
But I don't have NORTHWND!
ファイルにSQL文があるのでそれを実行して作成しました

PanelManagerクラス

Dumpを使えば、WPFやWindowsFormsのコントロールを簡単に表示させることができます
が、PanelManagerを使えば、より楽にGUIを使った処理を追加することが可能となります

WPF Sample

内容に応じてパラメータを変えたい場合などに便利に使えると思います

※詳細は以下を参照願います
Custom Visualizers

Snippets(Premium Edition)

LINQPadでもSnippetsを使う事が可能です

記述形式は、VisualStudioと同じ形式になるので、既に作成済みのものがあれば、LINQPadのSnippetsフォルダに移動すれば使用可能となります
※デフォルトは My Documents\LINQPad Snippets

Custom Snippets

Upload to Instant Share

現在開いているファイルの内容をアップロードし、共有するための機能です
実際にこの機能を使ってアップロードすると、処理中画面の後に、以下のような画面が表示されます

Share Query

ここに記載されている以下のURLを共有すれば他の人でもファイルをダウンロード可能となります
http://share.linqpad.net/93ovv8.linq

注意が必要なのが、ファイルの中身です
LINQファイルは、以下のように設定項目をXML、実際のソースはべた書きされるようなファイルとなっています

93ovv8.linq
<Query Kind="Expression">
  <Reference>&lt;RuntimeDirectory&gt;\System.dll</Reference>
  <Reference>&lt;RuntimeDirectory&gt;\System.Linq.dll</Reference>
</Query>

DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")

プロジェクト固有の設定(データベース接続先、参照しているdllなど)がある場合、その内容もアップされてしまいます
URLがわかれば誰でもダウンロード可能となるため、利用時は十分注意してください

コマンドラインからの実行

LINQPadで作成した.linqをコマンドラインから実行することも可能です
LPRUN.exeの引数に.linqファイルのパスを渡すだけです
※LPRUN.exeは、LINQPadをインストールしたフォルダあります

lprun foo.linq 単純に実行する場合は引数に渡すだけ

lprun -format=html foo.linq > output.html 実行結果を残す場合。-formatでデータの形式を指定可能です
-format={text|html|htmlfrag|csv|csvi}
出力されるデータは、.linq内で、Dumpを実行しているデータになります

lprun "queries\foo bar.linq" CustomArg 引数を渡すことも可能

lprun script1.linq | lprun script2.linq 別のクエリの実行結果を、pipeで次の処理に渡すことも可能

詳しくは以下を参照願います
LINQPad Command-Line and Scripting
※[Help]メニューの[Command-line Help]のリンクもここになっています

ショートカットキー

[Help]メニューの[Kyeboard/Mouse Shortcuts]をクリックするとショートカットの一覧が表示されます

上記に記載されていないもので、何個か便利なものを紹介します

key 概要
Ctrl+i 現在開いているソース内でのインクリメンタルサーチ
Ctrl+, 作成したLINQPadのソース検索(画面左下の領域 My Queriesタブの[Go to...]を押下したときと同じ)
Ctrl+k, x LINQPadで作成されているスニペットの表示(Premiumのみ)
Ctrl+k, s 選択した範囲のソースをif,usingなどで囲む(Premiumのみ?)

※キーボードショートカットをカスタマイズすることは現状できないようです
Can I Customize LinqPad shortcut keys?

作成したLINQPadのソース検索

ctrl + ,
押下にて、[Navigate To Query]画面が表示されます
※画面左下の領域 My Queriesタブの[Go to...]を押下したときと同じ画面です

Navigate To Query

画面下部にチェックボックスがありますが、検索する範囲の変更が可能です
ファイル名が一致するものが検索対象ですが、[Search Qeury Text]を選択することで、ファイル内の検索も可能となります

  • Search My Queries:My Queriesフォルダに設定したフォルダからファイル名が一致するものを検索します
  • Search Samples:サンプルファイルの中から検索します
  • Search Qeury Text:実際のファイル内を検索します

その他

Samples

LINQPadで実行可能なSampleファイルをダウンロードして、実行することが可能です
1. 画面左下[My Queries]の右側の[Samples]タブを選択
2. [Download/import more samples...]をクリック
3. [Browse Sample Libraries]画面が表示されるので、[Download C#5.0 in a Nutshell samples]など、必要なものをダウンロード

ここでダウンロードしたサンプルファイルが、[Samples]タブ内のフォルダに追加されていきます
まずは、サンプルをいろいろ実行してみて、何が出来るのか確認するのも良いと思います

LINQPad Visualizer

LINQPadのDumpメソッドで出力される内容はとても見やすいですが、その形式でVisualStudioでも閲覧できるようにしたツールです
Automatic way to move Visual Studio project into LINQPad?

Visual Studio 2012での設定方法

  1. C:\Users\ユーザ名\Documents\Visual Studio 2012\Visualizers
    https://code.google.com/p/linqpadvisualizer/ からダウンロードしてきた
    LINQPadVisualizer2012-104の中身
    LINQPad.exe
    をコピー

  2. C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE
    に、LINQPad.exeをコピー

使用方法

以下のようにウォッチウィンドウに、new System.WeakReference([参照したいオブジェクト])を設定するだけです
ビジュアライザーのアイコンをクリックすると、画面右側のような形で表示されます
LINQPadVisualizerSample

※Visual Studio 2013でも試しましたが、同じファイルを単純にコピーするだけでは動かなかったです
 ソースはダウンロード可能なので調べればわかると思いますが、まだ確認できていません

Tips

簡単なTipsがあればここに追記していきます

LINQPad Link

参考にしたLinkを紹介しておきます

LINQ Secrets Revealed: Chaining and Debugging
I’ve Left Query Analyzer Hell For LINQPad Heaven
Batch Updates and Deletes with LINQ to SQL

動画にて、LINQPadの使い方を説明してくれています
英語がわからなくても操作時の画面が表示されているので、それを参考にしました
LinqPad Episodes
Webcast: LINQPad Version 2 and Beyond
LINQPad - New Features for Entity Framework

Threadに関する資料(LINQPadは直接関係なさそうですが、C# 5.0 in a NutshellのThreadの内容よりも充実してそうだったので紹介)
Threading in c#