在 mvc 中使用 dapper 的动态结果
Posted
技术标签:
【中文标题】在 mvc 中使用 dapper 的动态结果【英文标题】:Dynamic results using dapper in mvc 【发布时间】:2017-03-27 09:10:49 【问题描述】:我正在尝试以下方式使用 dapper 和存储过程返回动态结果。我这样做的方式是否正确?
using (IDbConnection dbConnection = Connection)
dbConnection.Open();
var result = dbConnection.Query<dynamic>("LMSSP_GetSelectedTableData",
new
TableName = TableName,
LangaugeID = AppTenant.SelectedLanguageID,
UserID = AppTenant.UserID
, commandType: CommandType.StoredProcedure).ToList();
if (result != null)
// Added just for checking the data
foreach (var item in (IDictionary<string, object>)result.FirstOrDefault())
string key = item.Key;
string value = item.Value.ToString();
我的存储过程所做的是,我将传递任何表名并基于它返回结果/记录。所以,显然我的记录数,列将根据传递的表名而变化。
为了实现这一点,我使用了动态关键字和 dapper。
所以我的问题是如何将这些数据作为模型传递给视图,并根据属性/列数据类型在视图上呈现控件。我可以获取列 OR PropertyInfo 的数据类型吗?
但是,当 dapper 从数据库中检索记录时,它会以 dapper 行类型返回?
【问题讨论】:
如果您的存储过程根据输入返回不同的模式,这对我来说表明数据库设计不佳 @Rob 它只适用于少数表,主要是我们手中的系统表,而不是客户端。你能告诉我解决办法吗? 【参考方案1】:使用相同的 SP 从不同的表中获取数据会令人困惑(不是好的设计)。但是,为了从技术上解决您的问题,您可以创建具有控制信息列表的模型。控制信息示例
public class ControlInformation
public string Name get; set;
public dynamic Value get; set;
public string ControlType get; set;
// Applicable for drop down or multi select
public string AllValues get; set;
模型将具有 ControlInformations 列表
public List<ControlInformation> ControlInformations get; set;
View 将呈现控件(基于控件类型的部分视图) 例如:非常基本的情况,为 int 呈现不同的视图,为 rest 呈现另一个视图。我有 2 个局部视图“IntCtrl”和“StringCtrl”。
@foreach (var item in Model.ControlInformations)
if (@item.ControlType == "System.Int32")
html.RenderPartial("IntCtrl", item);
else
Html.RenderPartial("StringCtrl", item);
希望对您有所帮助。
【讨论】:
【参考方案2】:这里我们调用返回 Datatable 的方法:
public DataTable GetMTDReport(bool isDepot, int userId)
using (IDbConnection _connection = DapperConnection)
var parameters = new DynamicParameters();
parameters.Add("@IsDepot", isDepot);
parameters.Add("@userId", userId);
var res = this.ExecuteSP<dynamic>(SPNames.SSP_MTDReport, parameters);
return ToDataTable(res);
在此我们可以通过调用我们的自定义方法“ExecuteSP”来调用存储过程:
public virtual IEnumerable<TEntity> ExecuteSP<TEntity>(string spName, object parameters = null)
using (IDbConnection _connection = DapperConnection)
_connection.Open();
return _connection.Query<TEntity>(spName, parameters, commandTimeout:0 , commandType: CommandType.StoredProcedure);
这里是连接数据库的“DapperConnection”方法: 您可以使用键 ["MainConnection"]
提供连接字符串public class DataConnection
public IDbConnection DapperConnection
get
return new SqlConnection(ConfigurationManager.ConnectionStrings["MainConnection"].ToString());
最后我们调用“ToDataTable”方法来改变我们在 datatable 中的响应。我们将在 DapperRow 中收到来自数据库的响应,因为我们在存储过程中传递了动态类型。
public DataTable ToDataTable(IEnumerable<dynamic> items)
if (items == null) return null;
var data = items.ToArray();
if (data.Length == 0) return null;
var dt = new DataTable();
foreach (var pair in ((IDictionary<string, object>)data[0]))
dt.Columns.Add(pair.Key, (pair.Value ?? string.Empty).GetType());
foreach (var d in data)
dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
return dt;
【讨论】:
以上是关于在 mvc 中使用 dapper 的动态结果的主要内容,如果未能解决你的问题,请参考以下文章
获取 dapper.QueryMultiple 方法返回的结果集计数