LoginSignup
7
5

More than 5 years have passed since last update.

LINQの代わりにSQLを使用する方法

Last updated at Posted at 2018-10-23

はじめに

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を使用した形です。もっと良い方法があれば教えていただけると助かります。

7
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5