我正在研究一个代码示例,我只想听听他们做事方式的一些意见。他们使用普通的老式 ADO.NET。他们有一个称为 Read 的通用函数,可以返回 1 条记录。这是代码:
public static T Read<T>(string storedProcedure, Func<IDataReader, T> make, object[] parms = null)
{
using (SqlConnection connection = new SqlConnection())
{
connection.ConnectionString = connectionString;
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = storedProcedure;
command.SetParameters(parms);
connection.Open();
T t = default(T);
var reader = command.ExecuteReader();
if (reader.Read())
t = make(reader);
return t;
}
}
}
我不知道为什么:
- 他们使用
Func<IDataReader, T> make
作为方法签名的一部分?这样做有效率吗?有没有更好的方法/最佳实践来做到这一点? - 我不明白
T t = default(T);
?这样做有效率吗?有没有更好的方法/最佳实践来做到这一点? - 什么是
t = make(reader);
做?这样做有效率吗?有没有更好的方法/最佳实践来做到这一点?
调用函数看起来像这样:
public Customer GetCustomer(int customerId)
{
// Other code here
string storedProcedure = "MyStoredProcedure";
object[] parameters = { "@CustomerId", customerId };
return Db.Read(storedProcedure, Make, parameters);
}
private static Func<IDataReader, Customer> Make = reader =>
new Customer
{
CustomerId = reader["CustomerId"].AsId(),
Company = reader["CompanyName"].AsString(),
City = reader["City"].AsString
};
我不明白 Func Make
部分?有人可以向我解释这里发生了什么,这是否是好的做法。如有任何更改,我们将不胜感激,但请提供详细的示例代码:)
最佳答案
make
(具体化)的委托(delegate)非常通用且灵活,但在绝大多数情况下,IMO 都会做一些不必要的工作。就其作用而言 - 他们使用委托(delegate)作为回调来让调用者指定如何读取记录。
请注意,由于他们不希望消费者更改记录,因此他们可能应该公开IDataRecord
,而不是IDataReader
(任何阅读器还实现了记录)。
请注意,如果 TDS 流中有任何错误消息在第一条记录之后,所示方法将看不到它们 - 但这是一种边缘情况。如果您想减轻这种情况,您可以阅读到 TDS 流的末尾:
while(reader.NextResult()) {}
不过,就个人而言,我只是在这里使用 dapper-dot-net - 避免手动编写每个类型的代码:
var cust = connection.Query<Customer>("MyStoredProcedure",
new { CustomerId = customerId },
commandType: CommandType.StoredProcedure).Single();
这会将 MyStoredProcedure
作为存储过程执行,将 @CustomerId
和来自 customerId
的值传入,然后应用直接列<=== >属性/字段匹配以创建 Customer
记录,然后断言只有一个结果 - 并返回它。
关于c# - 创建通用检索方法以返回 1 条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6275184/