いつもはSQLServer使ってたんだけど、たまにはPostgreSQLも使ってみようかと思いまして、やってみた。

MVCはVisualStudioでテキトーにテンプレを使う。メンドーなので認証なし。そしたらNugetで下の3つのパッケージをインストール。

sample01

EFはEFのために必要。EFでPostgre使うためにNpgsql.EntityFrameworkが必要。これのためにNpgsqlが必要。みたいな感じらしい。EFは6。

そしたら次はWeb.configの設定

<!--ここはインストールすると勝手に入る-->
<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  <providers>
    <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>
<!--ここを手で追記-->
<system.data>
  <DbProviderFactories>
    <add name="Npgsql Data Provider" invariant="Npgsql" description="Data Provider for PostgreSQL" type="Npgsql.NpgsqlFactory, Npgsql" />
  </DbProviderFactories>
</system.data>
<!--接続文字列の指定-->
<connectionStrings>
  <add name="DefaultConnectionPGSQL" connectionString="Server=localhost;Port=5432;User Id=postgres;Password=*****;Database=hogedb" providerName="Npgsql" />
</connectionStrings>

手で追記する部分があるっぽい。ここ入れないと動かなかった。あとは接続文字列の指定。

ためしに作ったテーブルは下の二つ。日本語列名がいけるか試したいので日本語で。

--主キーがserial(SQLServerで言うIdentity)じゃないやつ
create table dbo.ホゲテーブル
(
ホゲ varchar(100) 
,数値 int
,CONSTRAINT wkpk PRIMARY KEY (ホゲ)
)
--主キーにserial(SQLServerで言うIdentity)
create table dbo.フガテーブル
(
フガid SERIAL
,テスト varchar(100) 
,数値 int
)

で、ワナが一つ。SQLServerはデフォでスキーマ名が「dbo」になる。なので、EFも何もしないとSQLに「dbo.table」みたいに書かれる。なので、Postgreのスキーマはdboで作っておいた方が吉。スキーマを変える場合は後述。

あとは、ためし実装。Model側。

public class HomeModels : DbContext
{
    public HomeModels() : base("DefaultConnectionPGSQL")
    {

    }
    public DbSet<HogeTable> HogeTables { get; set; }
    public DbSet<FugaTable> FugaTables { get; set; }

    public HomeViewModel getTable()
    {
        HomeViewModel resultModel = new HomeViewModel();
        resultModel.hogeT = this.HogeTables.Where(n => n.hogeval > 0).ToList();
        resultModel.fugaT = this.FugaTables.Where(n => n.数値 > 0).ToList();

        return resultModel;
    }
    public void modelAdd()
    {
        HogeTable addM = new HogeTable();
        addM.hogekey = DateTime.Now.ToString("yyyyMMddhhmmssfff");
        addM.hogeval = 123;
        this.HogeTables.Add(addM);


        FugaTable addM2 = new FugaTable();
        addM2.テスト = DateTime.Now.ToString("yyyyMMddhhmmssfff");
        addM2.数値 = 123;
        this.FugaTables.Add(addM2);
        this.SaveChanges();
    }

}
public class HomeViewModel
{
    public List<HogeTable> hogeT { get; set; }
    public List<FugaTable> fugaT { get; set; }
}

[Table("ホゲテーブル")] //テーブル名指定
public class HogeTable
{
    [Key] //主キーの設定
    [Column("ホゲ")] //列名指定
    public string hogekey { get; set; }
    [Column("数値")]//列名指定
    public int hogeval { get; set; }
}

[Table("フガテーブル", Schema = "dbo")] //スキーマ変えたいとき
public class FugaTable
{
    [Key] //主キーの設定
    public int フガid { get; set; }
    public string テスト { get; set; }
    public int 数値 { get; set; }
}

コントローラ側。HomeのIndexだけで、あと、データ追加用のAction。

HomeModels db = new HomeModels();
public ActionResult Index()
{
    HomeViewModel result = db.getTable();

    return View(result);
}

public ActionResult AddAction()
{
    db.modelAdd();
    return RedirectToAction("Index");
}

View側はこれ。

@model mvcdemo.Models.HomeViewModel
@{
    ViewBag.Title = "Home Page";
}

<div>
    @Html.ActionLink("Add","AddAction")
</div>

<h1>ホゲテーブル</h1>
<div>
    @foreach(var tmp in Model.hogeT)
    {
        <table>
            <tr>
                <td>
                    @tmp.hogekey
                </td>
                <td>
                    @tmp.hogeval
                </td>
            </tr>
            
        </table>
    }
</div>

<h1>フガテーブル</h1>
<div>
    <table>
        @foreach (var tmp in Model.fugaT)
        {
            <tr>
                <td>
                    @tmp.フガid
                </td>
                <td>
                    @tmp.テスト
                </td>
            </tr>
        }    
    </table>
</div>

実行結果で、何回か追加した後。

sample02

ちゃんとIDも振られてるし問題なし。。。フツーに使える。よかたよかた。

スキーマ変えたいときはテーブルのModel作るときに属性で「[Table("フガテーブル", Schema = "dbo")] 」って感じにする。全体通してやる場合はDbContextのクラスの中に下を入れておく。

public class HomeModels : DbContext
{
    public HomeModels() : base("DefaultConnectionSQLServer")//DefaultConnectionPGSQL
    {

    }
    //これを入れる
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("dbo");
    }
    public DbSet<HogeTable> HogeTables { get; set; }
    public DbSet<FugaTable> FugaTables { get; set; }
    ・・・

Modelのインスタンス作った時に呼ばれるやつではないかと。。。

ちなみにこの状態のまま、SQLServer側に同じテーブル作って、接続文字列の指定でSQLServer用のものを書けばそのままDB切り替えられました。ためしに色々やるのに便利。。。

Postgerはフツーに使えていい感じなんだけど、なんつーか、Postgreの管理ツールがびみょー。なんかいいの無いのかしら。

pgAdminなるものを使用してみたけど。微妙じゃない?なんつーか自分がMicrosoftに染められてるんだろーけど、インテリセンス弱すぎじゃない?あと、エラーとか警告とか結果の出力とかもろもろもろもろもろ。SQLServerのManegementStudioはやっぱりさすがにさすがにって感じなんだろーか。。。