2013-03-04 4 views
-1

Я пытаюсь написать оболочку, чтобы скрыть большую часть кода, который я нахожу, повторяя для каждого вызова db в Dapper. (а именно, Sql Connection, try, catch по умолчанию и, наконец). По сути, я хотел бы сделать что-то вроде следующего кода, но я понимаю, что из-за наличия динамического параметра я не могу использовать generics int this.Работайте для дженериков и динамических аргументов

так, как это я получаю ошибку:

Consider casting the dynamic arguments or calling the extension method without the extension method syntax (refering to the conn.Query method)

Есть ли способ, чтобы реорганизовать мой ExecuteQuery или на что-то вроде него, что работает?

public abtract class IDbAccessService 
{ 
    public LogService Logger { get; set; } 

    public virtual IEnumerable<T> ExecuteQuery<T>(string sql, dynamic param, string connString) 
     where T : BaseModel 
    { 
     using (var conn = DataAccessHelpers.GetOpenConnection(connString)) 
     { 
     try 
     { 
      return conn.Query<T>(sql, param).ToList<T>(); 
     } 
     catch (Exception ex) 
     { 
      Logger.Logger.Error(ex.Message, ex); 
      throw ex; 
     } 
     } 
    } 
} 
+1

Это 'finally' совершенно бесполезно. 'Close()' и 'Dispose()' делают то же самое (по крайней мере, обычно, я не знаю Dapper). И это 'использование' еще раз вызовет' Dispose() '. – svick

+0

Не связанный с вопросом, но я думаю, что блок 'finally' не нужен -' use' уже заботится о том, чтобы всегда утилизировать (и, следовательно, закрывать) соединение – MiMo

+0

@svick согласен, а 'catch' также бесполезен. Он создает запись в журнале и выдает исключение без stacktrace для последующего входа в систему еще раз –

ответ

1

Методы расширения не могут быть динамически отправлены. Так называем это без синтаксиса метода расширения:

static IEnumerable<T> ExecuteQuery<T>(string sql, dynamic param, string connStr) 
    where T : BaseModel 
{ 
    using (var conn = DataAccessHelpers.GetOpenConnection(connStr)) 
    { 
     return SqlMapper.Query(conn, sql, param).ToList<T>(); 
    } 
} 

Также у вас есть бесполезное протоколирования, который создает несколько записей журнала для одной ошибки и утилизации (это делается автоматически с помощью блока) бесполезного соединения.

Советы для обработки исключений:

  • Handle исключение и лог его
  • Wrap исключения за исключением высокого уровня и бросить эту обертку (вызывающий абонент будет обрабатывать это исключение высокого уровня, или же обернуть его)
  • не поймать исключение (вызывающий абонент будет делать первый или второй вариант)
1

Я попытался создать вспомогательные методы, как показано ниже.

private SqlConnection GetSqlConnection() 
     { 
      var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["con1"].ConnectionString); 
      sqlConnection.Open(); 
      return sqlConnection; 
     } 

public IEnumerable<T> GetAll<T>(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) where T : class 
     { 
      IEnumerable<T> objList; 
      using (var conn = GetSqlConnection()) 
      { 
       objList = conn.Query<T>(query, param: cmdParams, commandTimeout:0, commandType: cmdType); 
       conn.Close(); 
      } 
      return objList; 
     } 

public IEnumerable<dynamic> Query(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) 
     { 
      IEnumerable<dynamic> objDyn; 
      using (var conn = GetSqlConnection()) 
      { 
       objDyn = conn.Query(query, cmdParams, commandTimeout: 0, commandType: cmdType); 
       conn.Close(); 
      } 
      return objDyn; 
     } 

Из другого слоя:

var param = new DynamicParameters(); 
param.Add("@name", name); 
var objGroupsList = _iDapper.GetAll<CustomerDTO>("dbo.GetCustomersList", param, CommandType.StoredProcedure).ToList();