Подпись, которую вы ищете, это:
T GetData<T>(string cmdText, Func<SqlDataReader, T> func)
Тогда вы можете go вперед и написать свою функцию так:
public T GetData<T>(string cmdText, Func<SqlDataReader, T> func)
{
using (var conn = new SqlConnection(connectionStringBuilder.ConnectionString))
{
using (var cmd = new SqlCommand(cmdText, conn))
{
var reader = cmd.ExecuteReader();
return func(reader);
}
}
}
И вы бы использовали это выглядит так:
var result = GetData("select * from Foo", dr =>
{
while (dr.Read())
{
return new { property = dr["column"] };
}
throw new DataException();
});
Теперь это основано на том, как вы сказали, что хотели бы использовать его в своем вопросе.
Однако , вы сделали использование функции несколько затруднительно для вас, когда вы разбили реализацию - часть находится в GetData
, а часть в вызывающем коде.
Вам лучше использовать эту подпись:
IEnumerable<T> GetData<T>(string cmdText, Func<SqlDataReader, T> func)
Теперь вы можете написать метод следующим образом:
public IEnumerable<T> GetData<T>(string cmdText, Func<SqlDataReader, T> func)
{
using (var conn = new SqlConnection(connectionStringBuilder.ConnectionString))
{
using (var cmd = new SqlCommand(cmdText, conn))
{
var reader = cmd.ExecuteReader();
while (reader.Read())
{
yield return func(reader);
}
}
}
}
Преимущество теперь в том, что вызывающий код намного проще:
var results = GetData("select * from Foo", dr => new { property = dr["column"] });
Это возвращает столько строк данные в ответ на ваш запрос.
Если вы знаете, что ваш вызывающий код возвращает только одно значение, то вы можете сбросить .Single()
в конце вызова метода, чтобы получить один и только один результат.