1

我有一个数据访问层命名空间,其中包含大量重复代码(主要是设置命令对象并执行存储过程以返回添加到列表中的数据集)。我正在尝试编写一个返回List<T>. 我对泛型和委托都比较陌生。我的想法是有一个 Func 参数来创建添加到List<T>. 它将在通常的while dataReader.Read()块中调用。我的问题是,我将使用的数据集具有不同数量的列。

这是我到目前为止所拥有的:

private static List<T> ListFromDatabase<T,U>(String CommandName, SqlConnection SqlConn, Func<T,U> CreateListObj, 
    List<SqlParameter> ParamList = null)
{
    List<T> returnList = new List<T>();

    using (SqlCommand cmd = new SqlCommand(CommandName,SqlConn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        foreach (SqlParameter sp in ParamList)
        {
            if (sp.Value == null)
                sp.Value = DBNull.Value;
            cmd.Parameters.Add(sp);
        }

        SqlDataReader sdr = cmd.ExecuteReader();
        while (sdr.Read())
        {
            returnList.Add(CreateListObj);
        }
    }

    return returnList;
}

以我目前的理解水平,这可能是不可能的,因为我可能不得不针对不同数量的参数改变 Func 签名。这是可行的还是接近的?如果不是,我愿意采用不同的方法,如果有人可以提供帮助。提前谢谢了..

更新:这正是我想要的:

将数据读取器中的行转换为类型化结果

4

3 回答 3

1

做你想做的最优雅的方法是Tuple<T1,T2,T3...>通过传递一个接受具有特定数量和类型项目的元组的函数将 T 指定为 a,然后使用 Tuple.Create 使用来自 sdr 的行的内容生成该元组. 问题是,当从 DataReader 中获取字段时,它们会作为未确定类型的对象出现,而当您不知道它们的真实类型时传递它们的最安全方法是作为字符串,这意味着 CreateListObj 函数必须期望字符串和能够正确解析它们(因此期望元组中的特定列顺序)。

于 2012-08-14T19:39:00.803 回答
1

为什么不将您的代表传递SqlDataReader给您的代表IDataRecord?委托可以从数据记录中得到它所需要的;您可以控制对阅读器的迭代。

于 2012-08-14T19:42:39.247 回答
1

我过去所做的是定义“构建器”方法,这些方法接受IDataReader并返回它们定义的类型的对象(我将它们作为泛型类的方法而不是委托,但Func<IDataReader, T> 会做一样。

一般来说,我CommandBehavior.CloseConnectionExecuteReader调用中使用过,然后返回一个保存在阅读器上的类,实现IEnumerable<T> 然后在处理阅读器时关闭阅读器(以及底层连接),而不是先创建整个列表(你必须如果枚举器实际上根本没有枚举,请小心它会被清理)。

优点是我不必在定义时担心列号和类型的差异,只需在实现时(我不禁担心)。

于 2012-08-14T19:47:30.767 回答