MVC数据库优先-调用存储过程并得到错误



我有一个数据库优先的MVC项目,它使用MYSQL数据库,需要从中调用存储过程。我看到了如何访问SQL数据库存储过程的示例,并尝试将其复制并转换为使用MYSQL.Data.MySqlClient类(而不是System.Data.SqlClient类)。有人能帮我理解为什么我会出现以下错误吗?我是不是错过了什么。。。对于我缺少的MYSQL,在下面的MyDBContext方法中,我应该使用另一种方法吗?(我没有发现太多人在MVC中使用MYSQL存储过程,我知道这是一种罕见的情况,但我的情况确实需要这样。我看到的所有堆栈溢出回答的问题都不是将MYSQL与MVC一起使用。谢谢…)

当我尝试调用数据库时发生的错误。GetContinentList():"MySql.Data.MySqlClient.MySqlException:PROCEDURE dbName.ContinentListGet的参数数量不正确;应为4,得到0">

我的代码。。。

控制器测试代码(只是将结果循环作为测试以确保其工作):

private MyDbContext db = new MyDbContext();
public ActionResult Test()
{
var continentList = db.GetContinentList(1, "M", 1, 0);
var result = "";
foreach (sp_ContinentList c in continentList)
{
result = result + c.Common_Name + "(" + c.Scientific_Name + ")<br />";
}
return Content(result);
}

创建的模型:(我确保它与存储过程结果集列的输出匹配)

public class sp_ContinentList
{
public int ID { get; set; }
public string Common_Name { get; set; }
public string Scientific_Name { get; set; }
public int Profile { get; set; }
public string Area { get; set; }
}

MyDBContext.cs代码:

public class MyDbContext : DbContext
{
public MyDbContext() : base("MyDbContextConnectionString")
{
Database.SetInitializer<MyDbContext>(new MyDbInitializer());
}
public virtual ObjectResult<sp_ContinentList> GetContinentList(int continent, string group, int profile, int createCache)
{
MySqlParameter continentParam = new MySqlParameter("@vContinent", MySqlDbType.Int16);
continentParam.Direction = ParameterDirection.Input;
continentParam.Value = continent;
MySqlParameter groupParam = new MySqlParameter("@vGroup", MySqlDbType.VarChar, 50, group);
groupParam.Direction = ParameterDirection.Input;
MySqlParameter profileParam = new MySqlParameter("@vProfile", MySqlDbType.Int16);
profileParam.Direction = ParameterDirection.Input;
profileParam.Value = profile;
MySqlParameter createCacheParam = new MySqlParameter("@vCreateCache", MySqlDbType.Int16);
createCacheParam.Direction = ParameterDirection.Input;
createCacheParam.Value = createCache;
MySqlParameter[] spParams = new MySqlParameter[] {
continentParam, groupParam, profileParam, createCacheParam
};
return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<sp_ContinentList>("ContinentListGet", spParams);
}

我能够从下面的堆栈溢出链接中找到答案(它不是使用MVC,而是模仿MomentSurfer在构建MySqlParameter对象后调用存储过程的方式,这对我来说很有效):

链接:使用带有MySQL数据库的实体框架和模型设计器;t拾取存储的过程参数

public virtual ObjectResult<sp_ContinentList> GetContinentList(Nullable<int> continent, string group, Nullable<int> profile, Nullable<int> createCache)
{
MySqlParameter continentParam = new MySqlParameter("vContinent", MySqlDbType.Int16);
continentParam.Direction = ParameterDirection.Input;
continentParam.Value = continent;
MySqlParameter groupParam = new MySqlParameter("vGroup", MySqlDbType.VarChar, 50);
groupParam.Direction = ParameterDirection.Input;
groupParam.Value = group;
MySqlParameter profileParam = new MySqlParameter("vProfile", MySqlDbType.Int16);
profileParam.Direction = ParameterDirection.Input;
profileParam.Value = profile;
MySqlParameter createCacheParam = new MySqlParameter("vCreateCache", MySqlDbType.Int16);
createCacheParam.Direction = ParameterDirection.Input;
createCacheParam.Value = createCache;
MySqlParameter[] spParams = new MySqlParameter[] {
continentParam, groupParam, profileParam, createCacheParam
};
// New/Additional code needed:
StringBuilder sb = new StringBuilder();
sb.Append("CALL ContinentListGet(@vContinent, @vGroup, @vProfile, @vCreateCache)");
string commandText = sb.ToString();
return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<sp_ContinentList>(commandText, spParams);
}

我没有意识到我实际上必须把"CALL sproc_name()"作为命令文本,而且我传递参数的方式也不正确,需要进一步注意。不过,我不认为这是重复的,因为另一个例子不是MVC数据库优先/DBContext例子(这可能对那些选择使用MySQL数据库首先使用MVC数据库的人有用)。。但我会让你们决定的。

最新更新