Việc triển khai của Olivier là tốt. Nó sử dụng generics và giao diện cho mỗi thực thể nó thực hiện riêng của FillFromDataReader().
Bạn có thể mang nó xa hơn. Bằng cách sử dụng quy ước tất cả các mã hydrat hóa dữ liệu có thể được tập trung và trừu tượng đi.
Tôi sẽ giả định rằng tên thuộc tính lớp và tên cột của bạn giống nhau. Nếu không thì mã sau có thể được mở rộng để thêm các thuộc tính bí danh vào các tên thuộc tính. Đôi khi một thuộc tính được tính từ các giá trị khác trong đối tượng, thuộc tính này không thể được ngậm nước. Thuộc tính Ignore có thể được tạo và thực hiện trong lớp bên dưới.
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();
}
}
Có một vài cảnh báo trước ở mã trên. Các kiểu DBNulls và Nullable là các trường hợp đặc biệt và sẽ yêu cầu mã tùy chỉnh để xử lý chúng. Tôi thường chuyển DBNull thành null. Tôi chưa bao giờ gặp phải một trường hợp mà tôi cần phân biệt sự khác biệt giữa hai người. Đối với các kiểu Nullalbe, chỉ cần phát hiện kiểu Nullable và xử lý mã tương ứng.
Một ORM sẽ loại bỏ nhiều nguyên nhân gây đau đầu khi truy cập dữ liệu. Nhược điểm, là nhiều lần bạn được kết hợp với DTO và lược đồ cơ sở dữ liệu. Tất nhiên vấn đề này có thể được chứa bằng cách sử dụng abstractions.Nhiều công ty vẫn sử dụng các thủ tục được lưu trữ nghiêm ngặt, hầu hết các ORM rơi xuống khi họ buộc phải tiêu thụ các thủ tục được lưu trữ. Chúng không được thiết kế để làm việc với các thủ tục được lưu trữ.
Tôi đã viết khung truy cập dữ liệu có tên "Hypersonic". Nó trên GitHub, nó được thiết kế đặc biệt để làm việc với các thủ tục lưu sẵn. Đoạn mã trên là một thực thi ánh sáng của nó.
Nguồn
2013-01-01 19:42:07
Điều này về cơ bản là ORM. Tại sao không sử dụng ORM? Entity Framework hoạt động khá tốt, chúng tôi đang sử dụng nó trong một ứng dụng LOB lớn với hơn 400 khách hàng đang chạy một ứng dụng SAAS (với 3 máy tính avg mỗi máy) và phía máy chủ được lưu trữ trong các máy chủ của chúng tôi. –
Hãy xem một [ValueInjecter] (http://valueinjecter.codeplex.com/) và đặc biệt để [ví dụ này] (http://goo.gl/mD5OG), điều này ánh xạ một trình đọc dữ liệu vào một Danh sách các đối tượng miền theo cách bạn muốn làm. Regardas và chúc mừng năm mới! – Hugo