EntityFrameworkを使っているときでも、たまにSQLを直に書きたくなる場合がありますよね。そんな時はLambdicSqlを使うと便利です。そして、EntityFrameworkを使っている環境からLambdicSqlを使いやすい工夫を入れました。しかもそれでいてLambdicSql自体はDLL的にEntityFrameworkに依存したりはしていません。
DataContextクラスを指定できるようにしました。
EntityFrameworkでDBからモデルクラスを生成すると、こんな感じのものが生成されます。(若干省略してます)
publicpartialclass tbl_remuneration { publicint? staff_id { get; set; } publicstring payment_date { get; set; } publicint id { get; set; } publicdecimal? money { get; set; } } publicpartialclass tbl_staff { publicint id { get; set; } publicstring name { get; set; } } publicpartialclass ModelLambdicSqlTestDB : DbContext { publicvirtual DbSet<tbl_remuneration> tbl_remuneration { get; set; } publicvirtual DbSet<tbl_staff> tbl_staff { get; set; } }
これはLambdicSqlの定義に似ています。これをそのまま使えるようにしました。
publicvoid TestEFAndLambdic() { var query = Sql<ModelLambdicSqlTestDB>.Create(db => Select(new { name = db.tbl_staff.T().name, payment_date = db.tbl_remuneration.T().payment_date, money = db.tbl_remuneration.T().money, }). From(db.tbl_remuneration.T()). Join(db.tbl_staff, db.tbl_remuneration.T().staff_id == db.tbl_staff.T().id); var info = query.ToSqlInfo(_connection.GetType()); var datas = _connection.Query<SelectData1>(info.SqlText, info.Parameters).ToList(); }
T()がポイントですね。DbSet<>をスルーするものです。次のようなSQLになります。
SELECT tbl_staff.name AS"name", tbl_remuneration.payment_date AS"payment_date", tbl_remuneration.money AS"money"FROM tbl_remuneration JOIN tbl_staff ON (tbl_remuneration.staff_id) = (tbl_staff.id)
上記の例では素直にEFで書けばよいのですが、例えばOR結合を条件によって組み立てるときとか、Window関数を使うときとか、EFでは書きづらいもので利用してもらえばよいと思います。
//ORを任意の条件で組み立てるときとか var exp = Sql<DB>.Create(db => Condition(minCondition, 3000< db.tbl_remuneration.T().money) || Condition(maxCondition, db.tbl_remuneration.T().money < 4000)); var query1 = Sql<DB>.Create(db => SelectFrom(db.tbl_remuneration.T()).Where(exp)); //Window関数を使いたいときとか var query2 = Sql<DB>.Create(db => Select(new SelectData() { Average = Window.Avg(db.tbl_remuneration.T().money). Over<decimal>(null, new OrderBy(new Asc(db.tbl_remuneration.T().payment_date)), null) }). From(db.tbl_remuneration.T()));
名前解決のルールは若干違うので気を付けてください。
LambdicSqlのルールは、こちらです。EntityFrameworkとはテーブル名のルールが違っていますね。EFの場合はクラス名とテーブル名を対応させるルールで、しかも複数形と単数形の解決とか面倒なことをやってますね。とは言え、普通に生成するとEFも変数名とテーブル名は一致します。TableAttributeで指定している場合はLambdicSqlも同じルールで解決するので問題ないですね。問題ある命名している場合は、すみませんがテーブル定義を並べるクラスだけ別途作成お願いします。
是非EntityFrameworkユーザーの方もご利用お願いします!
LambdicSqlはメインでも使えて、脇役に回ってもいい仕事をするライブラリを目指しております。