创建通用检索方法以返回1条记录

时间:2011-06-08 06:51:46

标签: c# .net c#-4.0 ado.net

我正在编写代码示例,我只是想听听他们做事的方式的一些意见。他们使用普通的旧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部分?有人可以向我解释这里发生了什么,如果这是好的做法。如有任何更改,请提供详细的示例代码:)

2 个答案:

答案 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