今回は前回より複雑なSQLを発行します。
TO_CHAR(DATE, 'D') で、指定した日付が何曜日かが取れます。
今回は上記の関数を投げて、特定の曜日のみ抽出する処理を目標とします。
流れとしては、途中まで1回目の流れです。
saboten-sakura.hatenablog.com
.net のメソッドを定義(Oracle 関数とマッピング用)
返す型は、 TO_CHAR なので string を返します。
引数は、TO_CHAR 2で二つなんですが、第1引数は任意の値で、第2引数は'D'を渡します。
なので、 .net では DateTime を引数として渡します。
public static string DayOfWeekString(this DateTime? value) => throw new NotImplementedException();
.net で定義したメソッドを Oracle 関数とマッピング
GetMethod で定義した MethodInfo を取得します。
var method = typeof(StringExtension).GetMethod(nameof(StringExtension.DayOfWeekString), new Type[] { typeof(DateTime) })!;
取得した MethodInfo と Oracle の関数を定義付けします。
modelBuilder.HasDbFunction(method).HasTranslation(translation => new SqlFunctionExpression( "TO_CHAR", new SqlExpression[] { new SqlConstantExpression( Expression.Constant("D"), new StringTypeMapping( "VARCHAR2", DbType.String)), translation.First() }, true, new bool[] { false, false }, typeof(string), new StringTypeMapping( "VARCHAR2", DbType.String) ) );
上記を定義した後に、以下のコードを実装。
var context = new SampleDbContext(); var items = (from m in context.SampleTables where m.SampleDate.DayOfWeekString() == "3" select m); foreach (var item in items) { Console.WriteLine($"{item.Id} - {item.SampleDate?.ToString("ddd")}"); }
で、出力した SQL がこちら。
SELECT "s"."ID", "s"."SAMPLEDATE", "s"."SAMPLENUMBER" FROM "SAMPLETABLE" "s" WHERE TO_CHAR("s"."SAMPLEDATE", 'D') = '3'