2017-10-06 13 views
0

J'ai un projet MVC base de données qui utilise une base de données MYSQL et doit appeler une procédure stockée. J'ai vu des exemples d'accès à une procédure stockée de base de données SQL et j'ai tenté de la copier et de la convertir pour utiliser les classes MySql.Data.MySqlClient (au lieu des classes System.Data.SqlClient). Quelqu'un peut-il m'aider à comprendre pourquoi je reçois l'erreur ci-dessous? Ai-je manqué quelque chose ... existe-t-il une méthode différente que je devrais utiliser dans la méthode MyDBContext ci-dessous pour MYSQL qui me manque? (Je n'ai pas trouvé trop de gens qui utilisent des procédures stockées MYSQL dans MVC et je comprends que c'est un cas rare, mais j'en ai vraiment besoin pour ma situation.) Toutes les questions de réponses de débordement de pile je n'utilise pas MySQL avec MVC. ...)MVC Database-first - Appel d'une procédure stockée et obtention d'une erreur

L'erreur lorsque je tente d'appeler db.GetContinentList(): "MySql.Data.MySqlClient.MySqlException: nombre incorrect d'arguments pour la procédure dbName.ContinentListGet, attendu 4, a obtenu 0"

Mon code ...

code de test contrôleur (boucle juste à travers les résultats comme un test pour être sûr qu'il fonctionne):

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); 
} 

Modèle Créé: (je me suis assuré qu'il correspond à la sortie de la procédure stockée colonnes ResultSet)

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 code:

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); 
    } 

Répondre

0

I était capable de trouver la réponse du lien de débordement de pile ci-dessous (il n'utilise pas MVC, mais d'imiter MomentS la manière de Urfer d'appeler la procédure stockée après reste attaché aux objets MySqlParameter, cela a fonctionné pour moi):

Lien: Using the entity framework with a MySQL DB and the model designer doesn't pickup stored proc parameters

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); 
} 

Je ne savais pas que je devais réellement dire « CALL sproc_name() "en tant que texte de commande, et la façon dont je passais les params était également incorrecte et avait besoin de plus d'attention. Je ne pense pas qu'il s'agisse d'un doublon, car l'autre exemple n'est pas un exemple MVC Database-first/DBContext (cela peut être utile à quelqu'un qui choisit d'utiliser MVC Database d'abord en utilisant une base de données MySQL). Je vais vous laisser décider.