satymale’s diary

日々の忘備録

設定ファイルの値を取得する

設定ファイルの内容をControllerで使う方法が分からなかったので調べてみました。

config.json

{
    "Data": {
        "DefaultConnection": {
            "ConnectionString": "test"
        }
    }
}

Startup.cs

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv) {

   var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
       .AddJsonFile("config.json")
       .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

public IConfiguration Configuration { get; set; }

// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services) {
    services.AddMvc();
    services.Configure<Config>(Configuration);
}

Config.cs

public class Config {
    public Data Data { get; set; }
}

Data.cs

public class Data {
    public DefaultConnection DefaultConnection { get; set; }
}

DefaultConnection.cs

public class DefaultConnection {
    public string ConnectionString { get; set; }
}

HomeController.cs

public class HomeController : Controller {

    private Config _config;

    public HomeController(IOptions<Config> config) {
        _config = config.Options;
    }
}

ASP.NET5 + EntityFramework6でSQL Server Compact Editionを使う。

EntityFrameworkはCode FirstモードというコードからDBのテーブルを作る機能があるらしいですがまだそれは勉強していないので、先にテーブルを作ってEntityFrameworkから利用する方法を忘備録がてら残します。(2日ぐらいこれではまったので・・・)

NuGetでSQLServerCEのEntityFrameworkをインストールする

プロジェクトのリファレンスフォルダで右クリックをし、「NuGet パッケージの管理」をクリックします。 開かれたパッケージマネージャで「EntityFramework.SqlServerCompact」をインストールします。 f:id:satymale:20151105213529p:plain

DBを用意する

SQL ServerCEのDBであるsdfファイルを作成します。 昔はプロジェクトからファイルの追加で作れていた記憶があるのですが、ASP.NETのプロジェクトにはsdfファイルが存在しないので、SQL Serever Compact/SQLite ToolboxをVisual Studioにインストールします。

visualstudiogallery.msdn.microsoft.com

インストールが終わったら、SQL Server Compact/SQLite Toolboxからsdfファイルを作っていきます。

Data Connectionから右クリックを行い、「Add SQL Server Compact 4.0 Connection」をクリックします。 f:id:satymale:20151105120959p:plain

「Create」ボタンをクリックし、sdfファイル名を入力してから「OK」ボタンをクリックします。 f:id:satymale:20151105121600p:plain

テーブルを用意する

無事sdfファイルが作成されたら、テーブルを作っていきます。 sdfファイルにTablesがあるので、右クリックをして「Build Table」を選択します。

f:id:satymale:20151105122224p:plain

テーブル名や列を設定し、「Script!」ボタンをクリックします。 f:id:satymale:20151105122502p:plain

すると、SQLが生成されるので、「F5」ボタンか、赤枠で囲われたボタンをクリックします。 f:id:satymale:20151105122707p:plain

データを用意する

後でコードからテーブルの内容が取得できているか確認するために、データを用意しておきます。 テーブルで右クリックし、「Edit Top 200 Rows」をクリックします。 f:id:satymale:20151105123106p:plain

データを入力して「save」ボタンをクリックします。 f:id:satymale:20151105123636p:plain

コードを作成する

テーブルの準備ができたので、コードを作っていきます。 先ほど作成したテーブルを表すクラスを作ります。

using System.ComponentModel.DataAnnotations.Schema;

[Table("Hoge")]
public partial class Hoge {
    public int Id { get; set; }
    public string Col { get; set; }
}

Configurationを作成する

次にConfigurationを作ります。 このConfigurationは、後で作るコンテキストに渡す接続文字列がどのDB向けなのかを表すためのクラスになります。 これがないとデフォルトでSystem.Data.SqlClientが使用されます。

詳しくは以下に記載されています。 msdn.microsoft.com

これを私は知らなかったので、SQL Server CEの接続文字列を渡しても、Initial Catalogが指定されていないといったエラーメッセージが表示され四苦八苦してました。

using System.Data.Entity;
using System.Data.Entity.SqlServerCompact;

public class SqlserverCeConfiguration : DbConfiguration {
    public SqlserverCeConfiguration() {
        SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance);
    }
}

コンテキストを作ります。

using System.Data.Entity;

[DbConfigurationType(typeof(SqlserverCeConfiguration))]
public class HogeContext : DbContext {

    public HogeContext(string connectionString) : base(connectionString) {
    }

    public IDbSet<Hoge> Hoge { get; set; }
}

DNX Core 5.0を対象外にする

ビルドを行うと、DNX Core 5.0でEntityFramework.SqlServerCompact関連のアセンブリがない等のエラーが出ます。 f:id:satymale:20151105222016p:plain

Windows以外の環境で動かす予定はないので、DNX Core 5.0をproject.jsonから削除します。

"frameworks": {
    "dnx451": { },
    "dnxcore50": { }
},

"frameworks": {
    "dnx451": { }
},

値を取得する

実際にHogeテーブルに入っている値が取得できるか試してみましょう。

public IActionResult Index() {
    var context = new HogeContext(@"Data Source='D:\test.sdf';");
    var row = context.Hoge.FirstOrDefault();
    
    return View();
}

無事、値が取れましたね! f:id:satymale:20151105222152p:plain

Excelのシートを比較

最近Excelをよく使うようになって、シートの値の比較を効率よく出来るようになりました。

前は以下のようにIF文を使って差異を見つけていましたが

=IF(Sheet1!A1=Sheet2!A1,"○", "×")

Sheet1の条件付き書式で以下のようにやれば色も同時に付けれて一石二鳥です。

=INDIRECT("Sheet2!" & ADDRESS(ROW(), COLUMN())) <> A1

w2ui.loadにrecordsのJSONを返すURLを指定してはいけない

w2ui['グリッドのname'].load('JSONを返すURL');

上記のコードでサーバからデータを取得してグリッドに表示するが、データは以下の構造が正しい。

{
    "status" : "success",
    "total" : 1,
    "records" : [{
        "recid" : 1,
        "hoge" : "ほげ"
    }]
}

グリッドに直接指定していたrecords部分をloadでサーバから取ってくるものだと勘違いしていたため、以下のデータを返していて何も表示されなくて悩んでいた。

[{
    "recid" : 1,
    "hoge" : "ほげ"
}]

同じように勘違いする人がやはり居るらしく、w2uiの本家サイトに同じ質問がされていて回答が載っていて私も勘違いに気づいた。

w2ui gridチートシート

Renderの種類と表示

データ render 結果(デフォルトen-us) 結果(ja-jp)
テスト text テスト テスト
1234.5 int 1,235 1,235
1234.5 float:0 1,235 1,235
1234.5 float:1 1,234.5 1,234.5
1234.5 float:2 1,234.50 1,234.50
1234.5 number:0 1,235 1,235
1234.5 number:1 1,234.5 1,234.5
1234.5 number:2 1,234.50 1,234.50
1234.5 money $1,234.50 \1,235
1234.5 currency $1,234.50 \1,235
1234.5 percent 1,234.5% 1,234.5%
2000/01/01 age 15.7 years 15.7 years
2013/01/03 date Jan 3, 2013 2013年1月月03日
2013/01/03 date:yyyy/mm 2013/01 2013/01
1:52 pm time 13:52 13:52
13:52 time 13:52 13:52
13:52 time:h12 1:52 pm 1:52 pm
13:52 time:h24 13:52 13:52

1.4.3のバグ

  • 6448行目のformatTimeの引数に'h24:min'となっているが'h24:mi'が正しいので注意。
  • ロケールja-jpのdateは月が2つ続くので注意。

日本語表示

// 日本語のjsonファイルを適用
w2utils.locale('/lib/w2ui/locale/ja-jp.json');

セルの水平位置

{
    field: 'hoge', 
    caption: 'hoge',
    size: '40px',
    // styleで変更が出来る
    style: 'text-align:center'
}

FMEAを調べてみた。

プログラマからSEへ仕事の内容が変わり新しく学ぶ事の中で、FMEAが分からなかったので余暇を使って調べてみました。 ブログやホームページで色んな解説を読んでみましたが様々な解釈があり、書かれている事を鵜呑みにするのは危なさそうでした。 JIS C 5750-4-3:2011(日本工業規格)にFMEAについての定義があったので、まずはこれを読んでみることにしました。

JIS C 5750-4-3:2011の定義

FMEAはFailure Mode and Effects Analysisの略で、JIS C 5750-4-3には以下の様に定義されています。

FMEAは、システムの性能(直接の組み立て品及び全体のシステム又はあるプロセスの性能)に関する潜在的故障モード並びに それらの原因及び影響を明確にすることを目的とした、システムの解析のための系統的な手順である。

また以下の用語が定義されています。

アイテム

ディペンダビリティの対象となる、部品、構成品、デバイス、装置、機能ユニット、機器、サブシステム、システムなどの総称又はいずれか。

故障

アイテムが要求機能達成能力を失うこと。

フォールト

アイテムが要求機能を達成できない状態。
この規格では、"フォールト"を歴史的な理由で"故障"という言葉に言い換える。

故障の影響

運用、機能、又はアイテムの状態による故障モードの結果。

故障モード

アイテムにおける故障の様子。
注記 JIS Z 8115のF2の定義を次に示す。
故障状態の形式による分類。例えば、断線、短絡、折損、摩耗、特性の劣化など。

故障の様子、故障の状態と微妙な言い回しの違いや、故障とフォールトの定義が分かれているのに、フォールトを故障と言い換えると されていたりで、故障が状態を表しているのか事柄を表しているのか混乱してきます。

少し整理

書いている事を図にしてみました。 f:id:satymale:20151004234713p:plain

だいぶマシになってきましたが、まだ意味が分からないので、ファイルにログを出力するメソッドを例に当てはめてみます。 f:id:satymale:20151004235051p:plain

故障モードの定義にある、故障状態の形式による分類というのがあまり意味がよくわかりませんが、wikiにある定義を読むと意味が通ります。

製品システムを構成する項目(item)の構造的な(根源的な)破壊をいう。一方、故障とは機能障害である。何もなくただ機能しないということはありえなく、その製品が機能しない原因となる不具合が必ずある。この故障(機能障害)を引き起こした不具合、これが故障モードである。

なんとなく用語の関係が見えてきたので、これをベースに残りの記述を読んでいきます。

ログイン画面だけレイアウトテンプレートを使いたくない

レイアウトテンプレートのお陰で、メニューなどの共通部分を1箇所に纏めれて良いのですが、ViewStart.cshtmlはすべての画面に対して 効いているので、メニューなどが必要ないログイン画面にも適用されて困ってしまいます。

View直下のログイン画面のフォルダに_Layout.cshtmlを作る事でログイン専用のレイアウトテンプレートを作るのも1つの手だとは思いますが、 わざわざ1つの画面をテンプレートとコンテンツの2つに分けるのも微妙だなと思いました。

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
    </div>
</body>
</html>

とりあえず、ログイン画面ではLayout = nullとしてレイアウトが適用されないようにしてみて、期待する動きにはなったので これで良いか分かりませんが、これで進めてみようと思います。