我想要使用泛型来组合两个函数。
static public DataTable GetDataTable(SqlParameterHash parameters, string sql,
string connectionString, CommandType commandType = CommandType.StoredProcedure)
{
var da = new SqlDataAdapter(sql, connectionString);
da.SelectCommand.CommandType = commandType;
da.SelectCommand.CommandTimeout = 0;
foreach (SqlParameter Parameter in parameters)
{ da.SelectCommand.Parameters.Add(Parameter); }
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
static public DataSet GetDataSet(SqlParameterHash parameters, string sql,
string connectionString, CommandType commandType = CommandType.StoredProcedure)
{
var da = new SqlDataAdapter(sql, connectionString);
da.SelectCommand.CommandType = commandType;
da.SelectCommand.CommandTimeout = 0;
foreach (SqlParameter Parameter in parameters)
{ da.SelectCommand.Parameters.Add(Parameter); }
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
这就是我提出的:
static private T GetDataX<T>(T container
, SqlParameterHash parameters, string sql, string connectionString
, CommandType commandType = CommandType.StoredProcedure
) where T : System.ComponentModel.MarshalByValueComponent, new()
{
var da = new SqlDataAdapter(sql, connectionString);
da.SelectCommand.CommandType = commandType;
da.SelectCommand.CommandTimeout = 0;
foreach (SqlParameter Parameter in parameters)
{ da.SelectCommand.Parameters.Add(Parameter); }
da.Fill(container); // ERROR: cannot convert from 'T' to 'System.Data.DataTable'
return container;
}
但我得到上面显示的错误。
如果我将容器更改为动态,则会编译。但这似乎是一个黑客。 组合这两个函数的正确方法是什么?
答案 0 :(得分:3)
您可以添加Action
参数来为您要支持的每种类型执行填充:
static private T GetDataX<T>(SqlParameterHash parameters, string sql, string connectionString, Action<T, SqlDataAdapter> fillAction, CommandType commandType = CommandType.StoredProcedure)
where T : System.ComponentModel.MarshalByValueComponent, new()
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, connection);
da.SelectCommand.CommandType = commandType;
da.SelectCommand.CommandTimeout = 0;
foreach (SqlParameter Parameter in parameters)
{ da.SelectCommand.Parameters.Add(Parameter); }
T container = new T();
fillAction(container, da);
da.SelectCommand.Parameters.Clear();
return container;
}
然后你可以用这个方法编写你的其他方法:
static public DataTable GetDataTable(SqlParameterHash parameters, string sql,
string connectionString, CommandType commandType = CommandType.StoredProcedure)
{
return GetDataX<DataTable>(parameters, sql, connectionString, (dt, adapter) => { adapter.Fill(dt); }, commandType);
}
static public DataSet GetDataSet(SqlParameterHash parameters, string sql,
string connectionString, CommandType commandType = CommandType.StoredProcedure)
{
return GetDataX<DataSet>(parameters, sql, connectionString, (ds, adapter) => { adapter.Fill(ds); }, commandType);
}
答案 1 :(得分:1)
由于DataSet
和DataTable
是完全独立的类,并且您必须为每个类使用不同的SqlDataAdapter.Fill
重载,因此您将无法使用将两种方法简化为一种的通用方法。但是,您可以使用一种方法来减少重复代码,该方法接受一个委托,该委托定义在方法过程中如何处理SqlDataAdapter
。
public static DataTable GetDataSet(
SqlParameterHash parameters, string sql, string connectionString,
CommandType commandType = CommandType.StoredProcedure
)
{
DataSet ds = new DataSet();
UseDataAdapter(
parameters, sql, connectionString,
da => da.Fill(ds), commandType
);
return ds;
}
public static DataTable GetDataTable(
SqlParameterHash parameters, string sql, string connectionString,
CommandType commandType = CommandType.StoredProcedure
)
{
DataTable dt = new DataTable();
UseDataAdapter(
parameters, sql, connectionString,
da => da.Fill(dt), commandType
);
return dt;
}
public static void UseDataAdapter(
SqlParameterHash parameters, string sql, string connectionString,
Action<SqlDataAdapter> adapterAction,
CommandType commandType = CommandType.StoredProcedure
)
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, connection);
da.SelectCommand.CommandType = commandType;
da.SelectCommand.CommandTimeout = 0;
foreach (SqlParameter Parameter in parameters)
{ da.SelectCommand.Parameters.Add(Parameter); }
adapterAction(da);
da.SelectCommand.Parameters.Clear();
return dt;
}