Создание общего метода поиска для возврата 1 записи - PullRequest
5 голосов
/ 08 июня 2011

Я работаю над примером кода, и я просто хочу услышать некоторые мнения о том, как они что-то сделали. Они используют старый добрый 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 ]

3 голосов
/ 08 июня 2011

Делегат для make (материализация) довольно универсален и гибок, но в подавляющем большинстве случаев ИМО выполняет небольшую ненужную работу.С точки зрения того, что он делает - они используют делегата в качестве обратного вызова, чтобы заставить вызывающего абонента указать, как читать запись.

Примечание, поскольку они не ожидают, что потребитель изменить запись, вероятно, они должны показывать IDataRecord, а не IDataReader (любой читатель также реализует запись).

Обратите внимание, что если в потоке 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, затем применяет прямой столбец <===> соответствие свойства / полядля создания Customer записей, затем утверждает, что есть ровно один результат - и возвращает его.

2 голосов
/ 08 июня 2011

Они используют Func make как часть сигнатуры метода?Это эффективно сделать это так?Есть ли лучший способ / лучший способ сделать это?

Из-за общей природы метода T неизвестен, поэтому они не знают, как сопоставить читателя с Tсвойства.Таким образом, они оставляют эту ответственность вызывающему методу.На самом деле это достаточно эффективно, и это хорошая практика.

Я не понимаю, T t = default (T) ;?Это эффективно сделать это так?Есть ли лучший способ / лучший способ сделать это?

Поскольку T может быть либо значением, либо ссылочным типом, вы не можете присвоить ему значение null.default(T) возвращает значение по умолчанию для этого типа. В случае ссылочного типа это будет нулевым.В случае типа значения, например целочисленного, оно будет равно 0.

Что означает t = make (reader);делать?Это эффективно сделать это так?Есть ли лучший способ / лучший способ сделать это?

Он вызывает переданный делегат и присваивает результат t.

...