我正在编写代码示例,我只是想听听他们做事的方式的一些意见。他们使用普通的旧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
部分?有人可以向我解释这里发生了什么,如果这是好的做法。如有任何更改,请提供详细的示例代码:)
答案 0 :(得分:3)
make
(实现)的代表非常灵活多变,但IMO在绝大多数情况下都做了一些不必要的工作。就做什么而言 - 他们使用委托作为回调来让调用者指定如何读取记录。
注意,由于他们不希望消费者更改记录,他们可能应该公开IDataRecord
,而不是IDataReader
(任何读者也会实现记录)。< / p>
请注意,如果第一条记录后TDS流中有任何错误消息,则显示的方法将看不到它们 - 但这是一个边缘情况。如果您想减轻这种影响,可以阅读TDS流的末尾:
while(reader.NextResult()) {}
就个人而言,我只是在这里使用dapper-dot-net - 避免必须手动编写每个类型的代码:
var cust = connection.Query<Customer>("MyStoredProcedure",
new { CustomerId = customerId },
commandType: CommandType.StoredProcedure).Single();
这会将MyStoredProcedure
作为一个sproc执行,使用@CustomerId
中的值传递customerId
,然后应用直接列&lt; ===&gt;属性/字段匹配来创建{{ 1}}记录,然后断言只有一个结果 - 并返回它。
答案 1 :(得分:2)
他们使用Func make作为方法签名的一部分?这样做有效吗?有没有更好的方法/最佳做法?
由于该方法的通用性质T
未知,因此他们不知道如何将阅读器映射回T
属性。因此,他们将此责任留给方法的调用者。实际上,这是足够有效的,这是很好的做法。
我不明白T t =默认(T);?这样做有效吗?有没有更好的方法/最佳做法?
因为T
可以是值类型或引用类型,所以不能将其指定为null。 default(T)
返回此类型的默认值。如果是引用类型,则为null。如果是值类型,例如整数,则它将为0.
t = make(读者);做?这样做有效吗?有没有更好的方法/最佳做法?
它调用传递的委托并将结果分配给t
。