はじめに
Entity Frameworkで、DBの検索をLINQではなくSQLを使用する方法についてのメモです。LINQ文とSQL文を両方使用する際の、LINQ文に似た方法でSQLを発行させるメモです。
またSELECT文のみの記載です。
間違いや勘違いに関しましてはご指摘いただけると幸いです。
前提
Entity Frameworkを使用するSQL発行方法について記載します。
DBファーストで「ADO.NET Entity Data Model」で既に作成されているDBを取り込み、DbContextを継承したDefaultConnectionクラスからDBを使用します。
テーブルのイメージ
PersonTable |
---|
string PersonID |
strijng Name |
int Age |
string Mail |
本文
まず全体を記載します。
全体
private DefaultConnection db = new DefaultConnection();
db.Database.Log = sql =>
{
Debug.Write(sql);
};
StringBuilder sqBuildel = new StringBuilder(
@"SELECT
PersonID
, Name
, Age
, Mail
FROM PersonTable
WHERE PersonID = @personID");
string id = "A103";
object[] param = new object[] {new SqlParameter("@personID", id) };
string sql = sqBuildel.ToString();
var convert = db.Database.SqlQuery<PersonTable>(sql, param);
List<PersonTable> list = convert.ToList();
次に上から記載します。
DB接続の呼び出し
private DefaultConnection db = new DefaultConnection();
db.Database.Log = sql =>
{
Debug.Write(sql);
};
DBに接続するDefaultConnectionクラスを呼び出し、ログをとるようにします。
これは書籍『ASP.NET MVC 5 実践プログラミング』に載っていた方法です。
SQLを記載
StringBuilder sqBuildel = new StringBuilder(
@"SELECT
PersonID
, Name
, Age
, Mail
FROM PersonTable
WHERE PersonID = @personID");
発行したいSQLをStringBuilder型で記載しています。
StringBuilder型を使用している理由は、SQLは文字の量が多くなりやすいため、StringBuilder型で文字列処理を速くさせるためです。
2018/10/24追記
コメントにてご指摘いただきました通り、記載したようなSQL文の一発書きの場合、StringBuilder型を使用せず、string型で使用するほうが早くなります。
StringBuilder型は文字列操作を行うことに特化したクラスですので、ベースとなるSQLに、条件に応じてSQL文の追加や挿入が発生するという想定で使用したのですが、ここらへんはまだ勉強不足で申し訳ないです。
string sql = @"SELECT
PersonID
, Name
, Age
, Mail
FROM PersonTable
WHERE PersonID = @personID";
パラメーターの格納
object[] param = new object[] {new SqlParameter("@personID", id) };
この時、SQL文にある@personID
のように、@パラメータ名
と記載した箇所に入るパラメーターを用意します。
可変の値をSQL文に追加する方法はいくつかありますが、ここではSqlParameterクラスを使用して、当てはめるパラメーター名を指定し、使用する値をセットしています。
使用したSqlParameterクラスのメソッドの公式ドキュメントは以下です。
SqlParameter(string parameterName, object value)
SQLの発行
var convert = db.Database.SqlQuery<PersonTable>(sql, param);
List<PersonTable> list = convert.ToList();
Database.SqlQuery<TElement>
メソッドを使用してDbRawSqlQuery<TElement>
を取得します。
DbRawSqlQuery<TElement>
ではまだSQLは発行されていません。LINQでいうところのIQueryable<T>
を想像していただくとわかりやすいかもしれません。
IQueryable<T>
と同じくToList()
やforeach文
を使用することでSQLが発行されます。
ただIQueryable<T>
とは異なり、SQLの発行は一度のみで、遅延評価は行われません。また一度発行したDbRawSqlQuery<TElement>
を再度発行することはできません。
終わりに
SQLを発行させる方法はいくつかありますが、ログを取りたいためにEntity Frameworkを使用した形です。もっと良い方法があれば教えていただけると助かります。