【发布时间】:2023-03-09 11:34:01
【问题描述】:
我的应用程序中有一个页面,允许用户对数据库运行存储过程,这样他们就可以在不使用 SSMS 的情况下管理他们的数据或进行更改。使用SqlCommandBuilder.DeriveParameters 方法,我能够成功地获取并显示选择标记中的所有存储过程,并显示它们的输入和输出参数。
这里是合约类:
public class DatabaseUpdateModel
{
public int ClientId { get; set; }
public string StoredProcedureName { get; set; }
public List<SelectListItem> StoredProcedureNames { get; set; }
public Dictionary<string, SqlParamCollection> StoredProcedures { get; set; }
public Dictionary<int, string> ParameterInputs { get; set; }
public DatabaseUpdateModel()
{
StoredProcedureNames = new List<SelectListItem>();
StoredProcedures = new Dictionary<string, SqlParamCollection>();
ParameterInputs = new Dictionary<int, string>();
}
}
我分两步执行此操作 - 第 1 步发生在控制器的索引加载以获取存储过程名称:
服务方式:
private DatabaseUpdateModel GetDatabaseUpdateStoredProcedureNames(string connectionString)
{
_logger.LogTrace("Begin GetDatabaseUpdateModel service method");
SqlConnection connection = new SqlConnection(connectionString);
DBConnectionSetter.SetDBConnection(_SqlHelper, connectionString);
DatabaseUpdateModel model = new DatabaseUpdateModel();
IDataReader reader = _SqlHelper.GetDataReader("SELECT name FROM sys.objects WHERE type = 'p' ORDER BY name ASC", CommandType.Text, _appSettings.CommandTimeoutInSeconds, out connection, null);
while (reader.Read())
{
SelectListItem storedProcedure = new SelectListItem
{
Value = ((string)reader["name"]).Trim(' '),
Text = (string)reader["name"]
};
model.StoredProcedureNames.Add(storedProcedure);
}
reader.Close();
return model;
}
选择存储过程时,第 2 步通过 Ajax 发生
public DatabaseUpdateModel GetDatabaseUpdateProcedureParameters(string connectionString, string storedProcedureName)
{
_logger.LogTrace("Begin GetDatabaseUpdateProcedureParameters service method");
SqlConnection connection = new SqlConnection(connectionString);
DBConnectionSetter.SetDBConnection(_SqlHelper, connectionString);
DatabaseUpdateModel model = GetDatabaseUpdateStoredProcedureNames(connectionString);
connection.Open();
Contract.Shared.SqlParamCollection collection = new Contract.Shared.SqlParamCollection();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = storedProcedureName;
command.CommandType = CommandType.StoredProcedure;
SqlCommandBuilder.DeriveParameters(command);
foreach (SqlParameter param in command.Parameters)
{
if (param.Direction == ParameterDirection.Input)
{
collection.InputParameters.Add($"{param.ParameterName} - {param.SqlDbType}");
collection.SqlParameters.Add(param);
}
else
{
collection.OutputParameters.Add($"{param.ParameterName} - {param.SqlDbType}");
}
}
model.StoredProcedures.Add(storedProcedureName, collection);
connection.Close();
return model;
}
现在我一直在关注各种文章和资源以达到这一点,但现在我在将这些输入正确绑定到要通过操作或通过 ajax 提交的模型时遇到问题。这是我当前在视图中的代码(注释掉的行是我最近尝试让它工作的一种)。
@model DatabaseUpdateModel
<form>
<table id="summaryTable" class="table">
<thead>
<tr>
<td>Input Parameters</td>
<td>Output Parameters</td>
</tr>
</thead>
<tbody>
<tr>
<td>
<ul>
@if (!string.IsNullOrEmpty(Model.StoredProcedureName))
{
for (int i = 0; i < Model.StoredProcedures[Model.StoredProcedureName].InputParameters.Count(); i++)
{
<li>
@Model.StoredProcedures[Model.StoredProcedureName].InputParameters[i].ToString()<br />
@*<input id="databaseUpdateParam[@i]" name="parameter[@i]" asp-for="@Model.ParameterInputs[@i]" type="text" />*@
<input id="databaseUpdateParam[@i]"type="text" />
</li>
}
}
</ul>
</td>
<td>
<ul>
@if (!string.IsNullOrEmpty(Model.StoredProcedureName))
{
foreach (var param in Model.StoredProcedures[Model.StoredProcedureName].OutputParameters)
{
<li>
@param
</li>
}
}
</ul>
</td>
</tr>
</tbody>
</table>
</form>
@if (Model.StoredProcedures[Model.StoredProcedureName].InputParameters.Count() > 0)
{
<button type="submit" asp-action="Foo">Submit</button>
}
选择值时运行的 Ajax 函数:
function selectDatabaseUpdateStoredProcedure(clientId, storedProcedureName) {
var selected = $("#clientStoredProcedurePicker option:selected").val();
console.log(selected); // Selected Stored Procedure Name
$.ajax({
url: "/Process/GetDatabaseUpdateProcedureParameters?ClientId=" + clientId + "&StoredProcedureName=" + storedProcedureName,
success: function (data) {
console.log(data);
$("#summaryTableDiv").html(data);
}
});
}
我的假设,以及到目前为止我阅读的所有内容都表明,我应该能够简单地使用 name 属性来表示字典的键,并且标签中的值将对应于表单中输入的值提交。然而,我为实现这一目标所做的所有尝试都遇到了错误(例如,字典中不存在索引)。
如何通过控制器操作或 ajax 来实现?
【问题讨论】:
-
@Seabizkit 是的,我看到了那个帖子并尝试了一些非常相似的东西。我尝试将我的字典从
更改为 并多次更改我的输入标签助手以尝试获取提交的值。我目前正在阅读链接的博客文章。 -
@Seabizkit 好吧,我觉得自己像个白痴。在下面发布我的答案。
-
很高兴你把它分类了,是的,我可以为你做,但是当你和它斗争时你会学到很多东西,然后当你想出你喜欢的 yippy,我只是想让你有一个链接可以关注某些东西,我记得大约 10 年前我试图解决这个问题时......为什么链接更少,我也尝试了感觉像一百万种方法。一旦你知道它是如何工作的,你就可以将模型绑定到其他动态类型列表......
-
是的,这是我偶然发现的第一个链接。我在阅读之前写下了这个问题,因为这是我过去一两天一直在努力解决的问题。 :)
标签: c# jquery ajax asp.net-core