オリヴィエの実装は良いです。ジェネリックスとインターフェースを使用して、各エンティティに独自のFillFromDataReader()の実装を提供します。
あなたはそれをさらに進めることができます。慣例を使用することにより、すべてのデータハイドレーションコードを一元化して抽象化することができます。
クラスのプロパティ名と列の名前は同じであると想定します。そうでない場合は、次のコードを拡張して、プロパティ名にエイリアス属性を追加できます。プロパティがオブジェクト内の他の値から計算される場合がありますが、このプロパティはハイドレイトできません。Ignore属性は、以下のクラスで作成および実装できます。
public class DataAccess
{
/// <summary>
/// Hydrates the collection of the type passes in.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql">The SQL.</param>
/// <param name="connection">The connection.</param>
/// <returns>List{``0}.</returns>
public List<T> List<T>(string sql, string connection) where T: new()
{
List<T> items = new List<T>();
using (SqlCommand command = new SqlCommand(sql, new SqlConnection(connection)))
{
string[] columns = GetColumnsNames<T>();
var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
T item = new T();
foreach (var column in columns)
{
object val = reader.GetValue(reader.GetOrdinal(column));
SetValue(item, val, column);
}
items.Add(item);
}
command.Connection.Close();
}
return items;
}
/// <summary>
/// Sets the value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="item">The item.</param>
/// <param name="value">The value.</param>
/// <param name="column">The column.</param>
private void SetValue<T>(T item, object value, string column)
{
var property = item.GetType().GetProperty(column);
property.SetValue(item, value, null);
}
/// <summary>
/// Gets the columns names.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>System.String[][].</returns>
private string[] GetColumnsNames<T>() where T : new()
{
T item = new T();
return (from i in item.GetType().GetProperties()
select i.Name).ToArray();
}
}
上記のコードにはいくつかの注意点があります。DBNullとNullable型は特殊なケースであり、それらを処理するにはカスタムコードが必要になります。私は通常、DBNullをnullに変換します。私は、2つの違いを区別する必要があるケースに遭遇したことはありません。Nullalbe型の場合は、Nullable型を検出し、それに応じてコードを処理するだけです。
ORMは、データアクセスを処理する際の頭痛の種の多くを取り除きます。欠点は、多くの場合、DTOとデータベーススキーマに結合されていることです。もちろん、この問題は抽象化を使用することで封じ込めることができます。多くの企業は依然として厳密にストアドプロシージャを使用しており、ほとんどのORMは、ストアドプロシージャの使用を余儀なくされると失敗します。これらは、ストアドプロシージャで動作するようには設計されていません。
「ハイパーソニック」というデータアクセスフレームワークを作成しました。これはGitHubにあり、ストアドプロシージャで動作するように特別に設計されています。上記のコードは、それを簡単に実装したものです。