从DbDataReader读取/序列化时避免代码重复?

时间:2012-09-14 12:07:54

标签: c# design-patterns lambda dbdatareader

考虑下面的FetchData方法。它旨在避免每次要从数据库中获取某些数据时重复数据库查询代码。

List<MyData> myData = new List<MyData();
FetchData((IDataReader reader) =>
   {
       myData.Add(new MyData(reader.GetString(0), reader.GetInt32(1)));
   }, "usp_get_my_data");

它可以工作,但是如果这个对象创建可以以某种方式存在于FetchData方法中,那就太好了。

有更好的方法吗?

也许可以修改FetchData以直接返回某个类型X的列表?

protected void FetchData(Action<IDataReader> processor, String query)
{
    using (var connection = CreateConnection())
    {
        connection.ConnectionString = ConnectionString;
        connection.Open();

        using (var command = connection.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = query;

            using (IDataReader reader = command.ExecuteReader())
            {
                while (reader.read())
                {
                    processor(reader);
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

使用泛型可能吗?

protected IEnumerable<T> FetchData<T>(Func<IDataReader, T> processor, String query)
{
    using (var connection = CreateConnection())
    {
        connection.ConnectionString = ConnectionString;
        connection.Open();

        using (var command = connection.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = query;

            using (IDataReader reader = command.ExecuteReader())
            {
                while (reader.read())
                {
                    yield return processor(reader);
                }
            }
        }
    }
}

然后你可以随意使用枚举:

var myData = FetchData<MyData>(reader => new MyData(reader.GetString(0), reader.GetInt32(1)), "usp_get_my_data").ToList();

答案 1 :(得分:1)

您可以查看Dapper.Net这是一个包含三个不同助手的单个文件ORM:

  1. 执行查询并将结果映射到强类型列表
  2. 执行查询并将其映射到动态对象列表
  3. 执行不返回结果的命令
  4. 用于构建此miro-ORM的设计模式非常有用。 Dapper.Net is currently being used in StackOverflow