最近のSoma

ドキュメント書いたり、機能改善したりしています。

ドキュメントはまだ道半ばですが、「クイックスタート」と「SQLファイル」の項目はほぼほぼ終わり。

機能改善は細かいものをいくつかやりました。

  • Entity Frameworkが持っているキャッシュの機能を無効化。
  • LINQ to Entityの簡易化。
    • ObjectContextを触らない(Disposeの自動化)
    • IQueryable触らない(遅延実行しない)
    • Includeをタイプセーフに

キャッシュの機能を無効化

これは、すべてのクエリでMergeOption.NoTrackingを指定するようになったということです。これを指定するとオブジェクトコンテキスト(JPAだと永続コンテキストといったりしますが)にオブジェクトを溜め込まない。パフォーマンスあがります。そして、変更されたオブジェクトを覚えておいて後でまとめて更新系SQL発行という機能もなし。Insertメソッドを呼んだらINSERT文が発行され、Uupdateメソッドが呼ばれたらUPDATE文を発行するというわかりやすい仕組みになっています(そして後で述べるように検索についてもクエリのメソッドを呼んだら遅延実行させないで即時実行するようにしています)。

LINQ to Entityの簡易化

全件検索や関連先エンティティを含めた検索をLINQでこのように書けるようになりました。

internal class EmployeeRepository : RepositoryBase<SampleEntities, Employee>
{
    ...

    ///全件検索
    public IEnumerable<Employee> SelectAll()
    {
        return Query(employee => employee);
    }

    ///関連を含めた検索
    public Employee SelectByIdIncludingDepartment(int id)
    {
        return Query(employee => employee.Include(e => e.Department).Single(e => e.EmployeeId == id));
    }
}

Queryメソッドのでラムダのパラメータ(employeeのこと)の型はSystem.Data.Objects.ObjectQueryです。こいつに対してLINQでいろいろ記述できます。で、Queryメソッドの戻り値はIListです。これは、IQueryableならToListしてそこでSQLを即時に実行させています。これでSQLが思いもよらないところで遅延実行されたり、実行したときにはすでにObjectContextが閉じられていたりといったことがなくなります。

関連を含めた検索では、Includeメソッドにデリゲートを受け取ります。標準のAPIではIncludeメソッドは文字列しか受け取らないのですが、拡張メソッドでタイプセーフになるようにしています。このアイデアは、[C#]タイプセーフに、EntityFrameworkのIncludeを呼ぶを参考にさせてもらいました。


Somaは、DomaというよりもS2JDBCに似ているかも。SomaのRepositoryBaseがS2JDBCのAbstractServiceみたいなものですね。そして単純なクエリにはタイプセーフなAPIが使えて複雑なSQLにはSQLファイルが使えるとうところも共通点です。


次のリリースは、今週のどこかで考えています。