C# 解决泛型和动态参数的问题
我试图编写一个包装器来隐藏我发现自己在Dapper中为每个db调用重复的大部分代码。(即Sql连接、try、default catch和finally)本质上,我希望执行类似于以下代码的操作,但我理解,由于存在一个动态参数,因此不能以这种方式使用泛型int 我得到错误的方式是: 考虑在不使用扩展方法语法的情况下强制转换动态参数或调用扩展方法(参考conn.Query方法) 有没有办法重构我的C# 解决泛型和动态参数的问题,c#,dynamic,dapper,service-layer,C#,Dynamic,Dapper,Service Layer,我试图编写一个包装器来隐藏我发现自己在Dapper中为每个db调用重复的大部分代码。(即Sql连接、try、default catch和finally)本质上,我希望执行类似于以下代码的操作,但我理解,由于存在一个动态参数,因此不能以这种方式使用泛型int 我得到错误的方式是: 考虑在不使用扩展方法语法的情况下强制转换动态参数或调用扩展方法(参考conn.Query方法) 有没有办法重构我的ExecuteQuery或类似的东西 public abtract class IDbAccessServ
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;
}
}
}
}
公共广播类IDbAccessService
{
公共日志服务记录器{get;set;}
公共虚拟IEnumerable ExecuteQuery(字符串sql、动态参数、字符串connString)
其中T:BaseModel
{
使用(var conn=DataAccessHelpers.GetOpenConnection(connString))
{
尝试
{
返回conn.Query(sql,param.ToList();
}
捕获(例外情况除外)
{
Logger.Logger.Error(例如消息,例如);
掷骰子;
}
}
}
}
无法动态调度扩展方法。因此,在不使用扩展方法语法的情况下调用它:
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>();
}
}
静态IEnumerable ExecuteQuery(字符串sql、动态参数、字符串connStr)
其中T:BaseModel
{
使用(var conn=DataAccessHelpers.GetOpenConnection(connStr))
{
返回SqlMapper.Query(conn,sql,param).ToList();
}
}
此外,您还有无用的日志记录,它为单个错误创建多个日志条目,以及无用的连接处理(通过使用block自动完成)
异常处理提示:
- 处理异常并记录它
- 在高级异常中包装异常并抛出该包装(调用方将处理该高级异常,或者也将包装它)
- 不捕获异常(调用方将执行第一个或第二个选项)
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;
}
private SqlConnection GetSqlConnection()
{
var sqlConnection=new sqlConnection(ConfigurationManager.ConnectionStrings[“con1”].ConnectionString);
sqlConnection.Open();
返回sqlConnection;
}
公共IEnumerable GetAll(字符串查询,对象cmdParams=null,CommandType cmdType=CommandType.Text),其中T:class
{
IEnumerable对象列表;
使用(var conn=GetSqlConnection())
{
objList=conn.Query(Query,param:cmdParams,commandTimeout:0,commandType:cmdType);
康涅狄格州关闭();
}
返回对象列表;
}
公共IEnumerable查询(字符串查询,对象cmdParams=null,CommandType cmdType=CommandType.Text)
{
IEnumerable objDyn;
使用(var conn=GetSqlConnection())
{
objDyn=conn.Query(Query,cmdParams,commandTimeout:0,commandType:cmdType);
康涅狄格州关闭();
}
返回objDyn;
}
从另一层:
var param = new DynamicParameters();
param.Add("@name", name);
var objGroupsList = _iDapper.GetAll<CustomerDTO>("dbo.GetCustomersList", param, CommandType.StoredProcedure).ToList();
var param=new DynamicParameters();
参数添加(“@name”,name);
var objGroupsList=_iDapper.GetAll(“dbo.getCustomerList”,参数,CommandType.StoredProcedure.ToList();
那最后
是完全无用的Close()
和Dispose()
做同样的事情(至少通常,我不知道是否得体)。而using
将再次调用Dispose()
。这与问题无关,但我认为finally
块是不需要的,using
已经负责始终处理(并因此关闭)问题connection@svick同意,而且catch
也没用。它创建一个日志条目,并在没有stacktrace的情况下抛出异常,以便在以后再次记录。此代码不编译。您正在声明一个接口
,然后向其添加代码。将其更改为抽象类
或其他类型。另外,我认为如果您将类型参数T
添加到类/接口本身并将其从方法中删除(这样就有了一个方法公共虚拟IEnumerable ExecuteQuery(string sql、dynamic param、string connString)
此外,如果您发布了整个错误消息,而不仅仅是其中的一部分,并包括导致该错误的代码(或者说您已经发布的代码的哪一行导致该错误),则会有所帮助。