我有一个数据库优先的MVC项目,它使用MYSQL数据库,需要从中调用存储过程。我已经看到了如何访问SQL数据库存储过程并尝试将其复制并转换为使用MySql.Data.MySqlClient类(而不是System.Data.SqlClient类)的示例。有人可以帮助我理解为什么我得到以下错误?我错过了什么......我是否应该在MDQL下面的MyDBContext方法中使用我不同的方法? (我没有找到太多在MVC中使用MYSQL存储过程的人,我理解这是一个罕见的情况,但我的情况确实需要这个。所有堆栈溢出回答的问题我正在发布的不是MySQL和MVC一起使用。谢谢...)
我尝试调用db.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);
}
答案 0 :(得分:0)
我能够从下面的堆栈溢出链接中找到答案(它不是使用MVC,而是模仿MomentSurfer在构建MySqlParameter对象后调用存储过程的方式,这对我有用):
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()”作为命令文本,而我传递params的方式也是不正确的,需要进一步关注。我不认为这是重复的,因为另一个例子不是MVC数据库优先/ DBContext示例(这可能对选择使用MVC数据库的人有用 - 首先使用MySQL数据库)..但是我让你们决定。