お知らせ
2019年5月17日
C#ネタ その① EDMから実行したストアドプロシージャの戻り値をDTOに変換する
C#でストアドプロシージャを実行する場合、方法としてぱっと目についたのが、EntityDataModel(以下、EDM)を用いる方法でした。
Table型が返却されるストアドプロシージャの場合、ObjectResult型のEntityリストが返却されます。
そのまま利用するのが一番よいのですが、Entity自体は自動生成される為、後々の拡張性を考えると、
DTOへ変換したほうがよいという場面を考え、リフレクションを使った変換処理を作成しました。
今回は、変換元と変換先のDTOオブジェクトが必要になりますので、それぞれ総称型T・Uを用いてみます。
プロシージャから返却されるObjectResultをT型、DTOをU型として考えます。
public List<U> ObjectResultToDto<T, U>(IEnumerable<T> _data) { List<U> dtoList = new List<U>(); foreach (T item in _data) { // 総称型U(DTO)で指定されたクラスのインスタンスを取得 U _typeObject = (U) Activator.CreateInstance(typeof(U)); // 総称型T(ObjectResult)で指定されたObjectResultリストの行ごとにプロパティ値(フィールド名、値)を取得 foreach (PropertyInfo info in item.GetType().GetProperties()) { // 総称型U(DTO)で指定されたクラスのインスタンスのフィールドに設定 PropertyInfo propInfo = typeof(U).GetProperty(info.Name); if (propInfo != null) { propInfo.SetValue(_typeObject, info.GetValue(item)); } } dtoList.Add(_typeObject); } return dtoList; }
以下、DTOのインスタンスを生成する為、Activatorを使用します。
U _typeObject = (U) Activator.CreateInstance(typeof(U));
非常にお手軽ではありますが、パフォーマンスが悪く大量データ(10万件~)の場合、相当なボトルネックになりますので、
Reflection.Emit を使った動的生成にてインスタンス生成を行った方がよいかもしれません。