きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

DapperのQuery<dynamic>()の結果セットのフィールド名を取得する

ちょっと必要があったのでメモ。

 

Querydynamic()>が返すdynamicの実体はDapper.SqlMapper.DapperRowのコレクション

Query<dynamic()>()が返すdynamicの実体はDapper.SqlMapper.DapperRowのコレクションです。

f:id:kiyokura:20161209130932p:plain

 

このDapperRowはDapperのDapper.SqlMapperのprivateな型ですが、以下の通りIDictionary<string, object> の実装です。

github.com

 

ということで素直にIDictionary<string, object>にキャストしてみます。

  // SQLは実際にはSELECT * とか結果セット戻すストアドとか
  var result = cn.Query("SELECT 1 AS Id, 'Taro' AS Name , 20 AS Age"); 
  var fieldList = ((IDictionary<string, object>)result.First())
                    .Select(x => x.Key)
                    .ToList();

 

こんな感じで取れました。 f:id:kiyokura:20161209130950p:plain

 

どこでつかうん?

『どこでそんなもの使うの?』とか思う向きもかもしれないですが、クエリが返すフィールド名をハードコーディングしたくないケースって意外とあるというか、まあそんな感じで。 (例えばプログラム部分が『土管』に徹する場合(DB→JSONtとかDB→Excelとか)等だと、両端の柔軟性を生かす事ができると思います。というか、今回やりたいケースがまさにそれでした。)

Visual Studio Team Serviceで別のチームプロジェクトにリポジトリをforkして運用するメモ

Visual Studio Team Service(以下VSTS)で 別のチームプロジェクトにリポジトリをforkして運用してみよう と試行錯誤中です。とりあえず今やり始めたことをメモがてら。

 

実現したいこと

実現したいのはgithubでよくあるような『手元で修正してpull requestを送るためのfork』では無く。どちらかと逆で。『forkしてカスタマイズしたソースに、適宜分岐元の修正やバージョンアップを取り込む』という運用です。

有体に言うと、

  • パッケージ販売するソリューションを開発していて
  • 顧客後のカスタマイズが発生した場合はフォークしたプロジェクトで開発
  • フォーク先は標準パッケージのバージョンアップや修正も適宜取り込む

ということをやりたい。

リポジトリの話だけではなく、VSTSその他の機能(WorkItem関連とかCI系の機能とかビルドサービスとか)もベースの開発プロジェクトとは分離さているほうが望ましいという事情もあって。で、今回はこういうのがうまくできないか試してみようとしているという次第です。

 

私が知る限り2016/12/06現在はVSTSにはこういった簡単にリポジトリをforkできるような機能がない(はず)です。しかし所詮リポジトリはgitですのでremoteでフォーク元を追跡すればどうにもでできるはず。少しググると、割と似たようなことをVSTS(当時はVSO)やってている記事を見つけたので、参考にさせていただきながらやってみました。

www.woodcp.com

 

注意:

これから紹介する内容は、実際に私が実務で「これから本格的に利用しよう」と思ってまずは実験的に作ってみた構成のメモです。 ほぼこのまま実務で利用しようとしてはいますが、まだ本格的に使っているわけではないので、気が付いていない不味いことや問題点などがあることは十分に考えられます。お気づきの点があればぜひ、教えていただけると本当にうれしいです。

続きを読む

Visual Studio Code で ASP.NET Coreをデバッグ実行する(Win/Ubuntu/Mac)

表題のとおりです。 オフィシャルのドキュメントもあるので基本は悩むところないと思うのですが、現時点ではWindows環境のみproject.jsonに追記しないとうまくいかない点があります(そこでちょっと悩んだ)。

 

オフィシャルのドキュメントはこちら: Your First ASP.NET Core Application on a Mac Using Visual Studio Code | Microsoft Docs

 

上記ドキュメントはMacについて書かれていますが、SDKとnode.js、VSCodeのインストール方法が違うだけで、そこから先は大体同じだと思います。 取り急ぎ、WindowsUbuntu Desktopでは以下の手順でステップ実行できるところまでは確認しました。macは自分では試してないですが、そもそも参照してるドキュメントがmacようなのでmacでできない事は流石にないと信じています:p。

下はUbuntu Desktopでのデバッグ実行の様子。 f:id:kiyokura:20161125005037p:plain

 

必要なもの

必要なものは以下

  1. .NET Core SDK
  2. Visual Studio Code
  3. C# for Visual Studio Code (Visual Studio Code の Extension)
  4. Node.js
  5. yeoman(npm)
  6. bower(npm)
  7. generetor-aspnet(npm)

 

インストール方法

以下、入れていきます。

 

.NET Core SDK

オフィシャルサイトを参考に、各環境用のSDKをインストールします

.NET Core installation guide

全体的に丁寧な Step-by-step instructions になっていますので、迷うことはないと思います。 Windowsの場合は、[Select your environment]-[Command Line / Other]が該当します。

 

Visual Studio Code

こちらもオフィシャルサイトを参考に、各環境向けのガイドを見ながらインストールします。

Download Visual Studio Code

 

C# for Visual Studio Code

Visual Studio Code の C#拡張機能をインストールしておきます。 コード補完などの他、デバッグに関する機能などのあるので事実上必須です。

C# for Visual Studio Code (powered by OmniSharp)

インストール方法は上記サイトにもありますが、Visual Studio Codeのコマンドパレットで ext install csharp で入ります。

 

Node.js

次にNode.jsです。後述するYeomanを使ってプロジェクトのひな型を作るのにも使いますが、タスクランナーやbowerを動かすためにも必要なので、Yeomanは使わないとしても、事実上はほぼ必須なんじゃないでしょうか。 インストール方法はいろいろあると思います。

下記のオフィシャルサイトからバイナリを取得するなり、各ディストリビューションのパッケージ管理システムなどからインストールするなりしてください*1https://nodejs.org/

 

npmパッケージ類

Yeoman、Bower、generetor-aspnetをnpmでインストールします。 Yeomanはプロジェクトの雛型を生成するエンジンで、generator-aspnetはYeomanのASP.NET Coreのテンプレート生成アドオンです。Bowerは主にJavaScriptCSSなどのクライアントサイドライブラリのパッケージ管理システムです。generetor-aspnet が依存しているので、入れておきましょう。

これらのパッケージは一括でインストール可能です。nodeにパスが通っている個所で以下のコマンドでインストールできます。

npm install -g yo bower generator-aspnet

Linuxの場合、 -gオプションでこのあたりのnpmパッケージをインストールするときはsudoしないとエラーになると思います。nvm使うほうがいいんですかね?

 

アプリケーションの生成

generator-aspnetでアプリケーションの雛型を生成します。

 

1. 適当なディレクトリでコマンドラインからyo(Yeoman)を実行

> yo aspnet

初めてYeomanを実行したときは、情報の提供するかどうかみたいな質問が出てくるかもしれません。その場合はお好みでこたえておきましょう。

 

2. テンプレートの種類を選択

Yeomanが起動して、どのテンプレートを利用するか聞いてきます。今回は Web Appkication を選択しましょう。カーソルキーで選択肢を移動し、Enterで確定します。

f:id:kiyokura:20161125005822p:plain

 

3. UIデザインフレームワークを選択

次に、bootstrapかSemantic UIかどちらかを聞いてきます。今回はbootstrapを選びました。

f:id:kiyokura:20161125005832p:plain

 

4. アプリケーション名の入力

最後にアプリケーション名を入れます。任意ですが、今回はSampleAspNetAppとしました。

f:id:kiyokura:20161125005842p:plain

こで、カレントディレクトリ下にSampleAspNetAppディレクトリが作成され、プロジェクトの雛型が展開されます。 以下が表示された完了です。

f:id:kiyokura:20161125005848p:plain

 

Visual Studio Codeによるデバッグ実行

いよいよここからが本番です。 が、ここまで来たらもう、することはほぼ何もないです(^^;

 

プロジェクトを開く

Visual Studio Codeではディレクトリを指定して開くと、そのディレクトリをプロジェクト(ワークスペース)として扱います。Visual Studio Codeを起動してからディレクトリを開いても良いのですが、コマンドラインから起動しても楽です。 作成したプロジェクト のディレクトリに移動して、code .と入力します(「.(どっと)」が重要)。

> cd SampleAspNetApp
> code .

これで、カレントディレクトリを読み込んだ状態でVisual Studio Codeが起動します。

f:id:kiyokura:20161125005859p:plain

起動してしばらくすると、おそらく以下のようなメッセージが出ると思います。これについては後述します。 f:id:kiyokura:20161125005919p:plain

 

デバッグ用ファイルの生成

二つ表示されるメッセージのうち、「警告」となっている Required assets to build and debug are missing from ...のメッセージは、要するに「デバッグ実行に必要なVSCodeの設定ファイル類がないのけど作る?」という確認です。 [Yes]を選択しましょう。

こんな感じで必要なファイルが作成されます。 f:id:kiyokura:20161125005928p:plain

 

プロジェクトのrestore

下側のメッセージは「未解決の依存関係があるからrestoreしてね」ということなので、こちらもやっておきましょう。[Restore]ボタンをクリックすればOKです。ネットワーク越しに必要なものをダウンロードして依存を解決するので、少し時間がかかることがあります。 (事前にコマンドラインdotnet restoreをしている場合は表示されません)

 

シンボルファイルの生成のための設定(Windowsのみ)

Windowsの場合は、デバッグ用のシンボルを生成するproject.jsonに1行だけ設定を追加する必要があります。 詳細は Portable PDBs · OmniSharp/omnisharp-vscode Wiki · GitHub を参照のこと。

かいつまむと、project.json の buildOptionsのセクションに、"debugType": "portable"の記述を追加します。Visual Studio Code上で編集すればインテリセンスも効くので特に難しくないと思います。

  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

最初これが分からなくて、Windows環境でブレークポイントに止まらないし、ステップ実行もできないしで少し悩みました……。

 

デバッグ実行

では、デバッグ実行してみます。 事前にHomeController.csのIndexアクションメソッドにブレークポイントを張っておきます。

f:id:kiyokura:20161125010021p:plain

次に、左のナビゲーションからデバッグアイコン(虫みたいなやつ)をクリックしてデバッグ画面に入り、F5キーでデバッグ実行開始です。 f:id:kiyokura:20161125010049p:plain

しばらくするとブラウザが立ち上がりつつ、設定したブレークポイントで止まっているのが確認できます。 f:id:kiyokura:20161125010058p:plain

f:id:kiyokura:20161125010106p:plain

 

まとめ

mac用のチュートリアル記事を見ながらWindowsLinuxで環境を整えて試してみましたが、割とすんなりいきました。 名実ともにクロスプラットフォームと言って良いのではないでしょうか!

*1:ubuntuの場合はapt-getのリポジトリにある奴が激しく古かったりするので、ググって情報を探すとかしたほうがいいような気がします。この一連の手順でこれが一番面倒くさかったような気がします

書籍レビュー:改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

Twiterで行われてたWINGSプロジェクトの書籍レビュアー募集に応募し、献本いただきましたので少し遅くなったのですがレビューを書かせていただこうと思います。

 

体系立て無理なく入門できる本

全体的に丁寧に図示も交えながら体系立てて解説されているので、タイトルの通りJavaScriptをきちんと学習できる書籍だと思います。いわゆるサイ本などと比較すると言語仕様の深い部分での言及などは少ないですが、入門や脱初心者を目指すのであれば十分なレベルの内容だと思います。

他の初心者向けの入門書やWebサイトの入門者向けの記事などを見ながら始めてみた人が、ちゃんと文法や言語機能などに向き合い始めるのは最適の一冊ではないでしょうか。

 

改定の最大のポイントはES2015

この本は2010年に出版されたこちら https://www.amazon.co.jp/dp/4774144665 の改訂版でそちらも所有しているのですが、大きな改定ポイントはES2015について記述だと思いました。ES2015 については、独立したトピックスとして抜粋しているのではなく、各トピックスの中に自然に盛り込まれている(かつ、わかりやすいアイコンが付いている) スタイルで記述されています。

そのため、これからJavaScriptを学ぶのであれば自然にES2015の内容を取り入れることができるんじゃないかと思います。

そのほか、非同期処理で利用するPromiseについての記述が追加されていたり、StorageやWeb Workerなどについても追加されていたりします。逆に大きく削られているのはJQuery関連。このあたりから、最近のJavaScript界隈の情勢が反映されているな、という印象を受けました。

 

実務で抑えるべき周辺ツールにも言及

これは前の版からだったのですが、単に言語機能について記述しているのではなく、実務でJavaScriptを利用する上で最低限抑えておいた良いようなJasmineやJSDoc、GrurntやBableなどの周辺ツールについても言及があります。 もちろんそれらを使いこなすための細かなことまでには触れていませんが(それらのトピックだけで章や下手すれば本一冊分のボリュームになるでしょう)、そういったもの自体を知ったりとりあえず試してみるための糸口としては十分ではないかと思います。

ASP.NET CoreでEntity Framework Coreを使わずにDBに接続してみる

.NET CoreでDBアクセスといえば、各種紹介記事やドキュメント、チュートリアルでも Entity Framework Core がよく紹介されています。 個人的にはずいぶん小回りも効くようになってすごくよくなってると思いますし、.NET CoreでのDBアクセス周りは、まずはEntity Framework Coreを使うところから始めてよいように思っています。

とはいえ、そこはやはりコンテキスト次第ではあると思うので、後学のために調べてみました。

 

System.Data.SqlClientを使ってみる

では実際に試してみます。 適当にASP.NET CoreのWebアプリケーションを作成しておきます(認証は無しを選んでおきます)。環境はVS2015 Community 以上を想定します。 対処のDBはとりあえず SQL Serverとします。

CoreFxにおける非EFについのてドキュメントがぱっとみで見当たらなかったのですが、『きっとSystem.Data.SqlClientがそのまま存在するに違いない』と思って検索してみると……やはりありました。

www.nuget.org

ということでまずはインストールしておきます。

PM> Install-Package System.Data.SqlClient
  GET https://api.nuget.org/v3/registration1-gz/system.data.sqlclient/index.json
  GET https://www.nuget.org/api/v2/curated-feeds/microsoftdotnet/Packages(Id='System.Data.SqlClient',Version='4.1.0')
  OK https://www.nuget.org/api/v2/curated-feeds/microsoftdotnet/Packages(Id='System.Data.SqlClient',Version='4.1.0') 282ms
  OK https://api.nuget.org/v3/registration1-gz/system.data.sqlclient/index.json 376ms
'nuget.org' からパッケージ 'System.Data.SqlClient 4.1.0' を取得しています。
NuGet パッケージ System.Data.SqlClient.4.1.0 をインストールしています。
'System.Data.SqlClient 4.1.0' が CoreFxDbSample に正常にインストールされました
NuGet の操作の実行に 37.83 ms かかりました
経過した時間: 00:00:02.3787366

f:id:kiyokura:20161022000202p:plain

スクリーンショットにはないですが、ドリルダウンすると、System.Data.Common何かもちゃんと在って、見ていることが分かります。

 

プロバイダがインストールされたので、適当なSQL Serverに接続してみます。読むテーブルは取り合ずこんな感じのシンプルな奴だと思ってください。

CREATE TABLE [dbo].[User] (
  [Id] INT NOT NULL,
  [Name] NVARCHAR (50) NOT NULL,
  [Email] NVARCHAR (255) NOT NULL,
  [BirthDay] DATETIME NOT NULL,
  PRIMARY KEY CLUSTERED ([Id] ASC)
);

データには何か適当にレコードを入れておきました。

 

とりあえずサンプルなのでHomeControllerに直接書いてみます。何の変哲もない、ADO.NETで普通に接続型でDBを読む場合とまったく同じコードだと思います。 接続文字列はVisual Studioのサーバーエクスプローラーで選択してプロパティからコピーしたものをそのまま使っています*1

// HomeController.cs
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Data.SqlClient;
namespace CoreFxDbSample.Controllers
{
  public class HomeController : Controller
  {
    public IActionResult Index()
    {
      ViewBag.Users = new List<string>();
      using (var con = new SqlConnection("<接続文字列>"))
      using (var cmd = new SqlCommand("SELECT Name FROM Users WHERE Id <= @Id", con))
      {
        cmd.Parameters.Add(new SqlParameter()
        {
          ParameterName = "Id",
          Value = 2,
          DbType = System.Data.DbType.Int32
        });

        con.Open();
        using (var dr = cmd.ExecuteReader())
        {
          while (dr.Read())
          {
            ViewBag.Users.Add(dr["Name"].ToString());
          }
        }
      }
      return View();
    }
  }
}

ついでに結果を見るためにHome/Index.cshtmlもばっさり書き換えておきます。

<!-- Home/Index.cshtml -->
@{
  ViewData["Title"] = "Home Page";
}
<h1>DataReader Sample</h1>
<ul>
  @foreach (var item in ViewBag.Users)
  {
  <li>@item</li>
  }
</ul>

実行してみると、普通に表示されます。 f:id:kiyokura:20161021233323p:plain

この例のとおり、DbConennction, DbCommand , DbParameter, DbDataReaderなど、ADO.NETの基本的な仕組みはポーティングされていて、SQL Server用のプロバイダでもちゃんと実装されていることが分かりました。

NetFxのADO.NETを接続型で使う場合と比較して特に違和感が無い…というか全く同じように使えることが期待できますね。

 

NetFxのADO.NETと比較した制限(2016/10/15 現在)

とはいえ、そのまま移植されているわけではなく、現時点(.NET Core 1.0.1)では利用できない機能がいくつかあります。

 

DataSetやDataTableはまだ実装されていない(もうすぐ入りそう)

DataSetやDataTable、DataAdapterなど、ADO.NETの非接続型の機能を提供するクラスは、現時点(.NET Core 1.0.1)では実装されていません(何か依存物のコンパイルを通すためか、DataTableのみ空で実装はされている模様)。

これらはNetFxでももはやレガシーな機能ですし、WinFormやWebFormなどDataSetを前提としたコンポーネントを活用する(これまたレガシーな)機能は.NET Coreで実装される予定が(今のところ)なさそうなので、このまま実装されずに終わるかな……と思っていたのですが、なんと、ごく最近になってcorefxのmasterにマージされました*2

ということで、近い将来のリリースあたりで入ってくるんじゃないかと思います。

 

 

DataTableに依存した機能は使えない(2016/10/15 現在)

DataTable自体を欲していなくても、DataTableが無いと利用できない機能というのがいくつかあります。私が思いついたのは以下です。 (ただし前述のとおりDataTableが実装されてくれば、将来的にはこれらもちゃんと機能するようになることが期待できそうです。)

Table Value Parameter (テーブル値パラメータ/TVP)

SQL Serverの便利な機能であるTable Value Parameterを.NETのコードから利用する場合、DataTableに格納して渡すことになります。しかし、.NET Core 1.0.1ではDataTableが実装されていないので利用することができません。

SqlConnection.GetSchema

接続先のスキーマ情報を取得するメソッドですが、この戻り値がDataTableだるため、現在は利用できません(GetSchemaが実装されていない)。

 

まとめ

.NET Core 1.0.1の現時点でもDbConnection, DbCommand, DbDataReaderなどの基本的なものは実装されていて、NetFxのADO.NETで利用するのと違和感なく利用できるようです。 現時点のリリースではDataSetやDataTableがまだ実装されていませんが、近い将来のリリースでは含まれてきそうです。

*1:SQL Server認証の場合はパスワードが*になるので書き換える必要があります

*2:これらレガシーな機能がまるっと実装された(だだしTableAdapter はなさそう)理由はよくわかりません。ただ後述のとおりDataTableに依存した機能がいくつかあって、そのためDataTableの実装を望む声は上がっていたようですので、そのあたりも関係しているかもしれません。DataSetについてはどうなんよと思うのですが、ちょっとDataTableのソースを眺めてみた感じではそのなかでもDataSetに依存したコードもあるように見えたので、そう簡単に切り離せるものでは無いのかもしれません。