EntityFrameworkを使っているときでも、たまにSQLを直に書きたくなる場合がありますよね。そんな時はLambdicSqlを使うと便利です。そして、EntityFrameworkを使っている環境からLambdicSqlを使いやすい工夫を入れました。しかもそれでいてLambdicSql自体はDLL的にEntityFrameworkに依存したりはしていません。
DataContextクラスを指定できるようにしました。
EntityFrameworkでDBからモデルクラスを生成すると、こんな感じのものが生成されます。(若干省略してます)
public partial class tbl_remuneration
{
public int? staff_id { get; set; }
public string payment_date { get; set; }
public int id { get; set; }
public decimal? money { get; set; }
}
public partial class tbl_staff
{
public int id { get; set; }
public string name { get; set; }
}
public partial class ModelLambdicSqlTestDB : DbContext
{
public virtual DbSet<tbl_remuneration> tbl_remuneration { get; set; }
public virtual DbSet<tbl_staff> tbl_staff { get; set; }
}
これはLambdicSqlの定義に似ています。これをそのまま使えるようにしました。
public void TestEFAndLambdic()
{
var query = Db<DB>.Sql(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 datas = _connection.Query<SelectData1>(query).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では書きづらいもので利用してもらえばよいと思います。
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));
var query2 = Db<DB>.Sql(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はメインでも使えて、脇役に回ってもいい仕事をするライブラリを目指しております。