C# 使用func时,我能否以任何方式更改签名<&燃气轮机;代表?
我有一个数据访问层名称空间,其中包含大量重复代码(主要是设置命令对象和执行存储过程以返回添加到列表中的数据集)。我正在尝试编写一个返回C# 使用func时,我能否以任何方式更改签名<&燃气轮机;代表?,c#,.net,c#-4.0,C#,.net,C# 4.0,我有一个数据访问层名称空间,其中包含大量重复代码(主要是设置命令对象和执行存储过程以返回添加到列表中的数据集)。我正在尝试编写一个返回列表的通用工厂方法。我对泛型和委托都比较陌生。我的想法是使用Func参数创建添加到列表中的对象。它将在通常的while dataReader.Read()块中调用。我的问题是,我将使用的数据集具有不同的列数 以下是我到目前为止的情况: private static List<T> ListFromDatabase<T,U>(String C
列表的通用工厂方法。我对泛型和委托都比较陌生。我的想法是使用Func参数创建添加到列表中的对象。它将在通常的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;
}
private static List ListFromDatabase(字符串CommandName、SqlConnection SqlConn、Func CreateListObj、,
列表参数(列表=空)
{
List returnList=新列表();
使用(SqlCommand cmd=newsqlcommand(CommandName,SqlConn))
{
cmd.CommandType=CommandType.storedProcess;
foreach(参数列表中的SqlParameter sp)
{
如果(sp.Value==null)
sp.Value=DBNull.Value;
cmd.Parameters.Add(sp);
}
SqlDataReader sdr=cmd.ExecuteReader();
while(sdr.Read())
{
returnList.Add(CreateListObj);
}
}
退货清单;
}
在我目前的理解水平上,这可能是不可能的,因为我可能需要为不同数量的参数改变Func签名。这是可行的,还是接近的?如果没有,我愿意接受不同的方法,如果有人能帮忙的话。非常感谢
更新:这正是我想要的:
最优雅的方法是将T指定为元组
,方法是传递一个函数,该函数接受具有特定数量和类型项的元组,然后使用Tuple.Create使用sdr中的行内容生成该元组。问题是,当从DataReader中获取字段时,字段会显示为类型不确定的对象,当您不知道字段的真实类型时,传递字段的最安全方式是字符串,这意味着CreateListObj函数必须预期字符串并能够正确解析它们(因此在元组中预期特定的列顺序).为什么不将您的SqlDataReader
作为IDataRecord
传递给您的学员?委托人可以从数据记录中获得所需信息;您可以控制对读取器的迭代。我过去所做的是定义“builder”方法,这些方法采用IDataReader
,并返回它们定义的对象类型(我将它们作为泛型类的方法而不是委托,但Func
也会这样做)
通常,我在ExecuteReader
调用中使用了CommandBehavior.CloseConnection
,然后返回一个类,该类保存在读卡器上,实现了IEnumerable
,然后在释放读卡器时关闭读卡器(以及底层连接),而不是首先创建整个列表(如果枚举器实际上根本没有枚举,则必须小心清理它)
其优点是,我不必在定义时担心列数和类型的差异,只需在实现时(在实现时我会情不自禁地担心).我会做一些类似于你提议的事情。我想知道,你对你的实施有什么不满意?@BrianDishaw我不知道如何“充实”/实现func委托,特别是因为参数的#会有所不同。U
类型参数是什么?这不会编译,因为您正试图将func
添加到列表中。听起来您想要func
并将读取器传递给func,以创建t
?@L的实例ee是的,不会编译,这就是我被卡住的地方。。我知道U现在还没有解释。。你的建议很接近,但是我必须在为委托传递的函数中进行迭代,我希望在工厂发生的迭代中调用委托。@StatsViaCsh-迭代将在列表fromdat中进行abase
method:while(sdr.Read()){returnList.Add(func(sdr));}
我对IDataRecord不太熟悉。现在看看这个,thx。有趣的方法,我不知道我是否能完全按照您描述的方式实现它,但我会尝试一下。