Implementacja Oliviera jest dobra. Używa generycznych i interfejsów, dając każdemu podmiotowi własną implementację FillFromDataReader().
Możesz go zabrać dalej. Używając konwencji, cały kod nawodnienia danych może zostać scentralizowany i usunięty.
Zamierzam założyć, że nazwy klas i nazwy kolumn są takie same. Jeśli tak nie jest, można rozszerzyć poniższy kod, aby dodać atrybuty aliasów do nazw właściwości. Czasami własność jest obliczana na podstawie innych wartości w obiekcie, ta właściwość nie może być uwodniona. Atrybut Ignoruj można utworzyć i zaimplementować w poniższej klasie.
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();
}
}
W powyższym kodzie znajduje się kilka zastrzeżeń. Typy DBNulls i Nullable są przypadkami specjalnymi i będą wymagać niestandardowego kodu, aby sobie z nimi poradzić. Zwykle konwertuję DBNull na null. Nigdy nie spotkałem się z przypadkiem, w którym potrzebowałem rozróżnić różne między nimi. W przypadku typów Nullalbe wystarczy wykryć typ Nullable i odpowiednio obsłużyć kod.
ORM może usunąć wiele problemów związanych z dostępem do danych. Minusem jest to, że wiele razy jesteś połączony ze schematem DTO i schematem bazy danych. Oczywiście problem ten można ograniczyć za pomocą abstrakcji.Wiele firm nadal stosuje ściśle przechowywane procedury, większość ORM spada, gdy są zmuszeni do korzystania z procedur przechowywanych. Po prostu nie są zaprojektowane do pracy z procedurami przechowywanymi.
pisałem ramy dostępu do danych o nazwie „Hypersonic”. Jest na GitHub, jest specjalnie zaprojektowany do pracy z procedurami przechowywanymi. Powyższy kod jest lekką implementacją tego kodu.
To jest zasadniczo to, co robi ORM. Dlaczego nie skorzystać z ORM? Entity Framework działa całkiem nieźle, używamy go w dużej aplikacji LOB z ponad 400 klientami korzystającymi z aplikacji SAAS (z średnio ponad 3 komputerami), a serwer jest hostowany na naszych serwerach. –
Spójrz A [ValueInjecter] (http://valueinjecter.codeplex.com/) i specjalnie [danego przykład] (http://goo.gl/mD5OG) Mapuje czytnika danych do Lista obiektów domeny w taki sposób, w jaki chcesz to zrobić. Regardas i szczęśliwego nowego roku! – Hugo