2009-06-18 4 views
4

Visual Studio Entity Frameworkデザイナを使用できる最新のMysqlコネクタがあります。それはうまくいっていますが、私はストアドプロシージャを追加しました。エンティティフレームワークをMySQL DBで使用すると、モデルデザイナーがプロックパラメータを格納しません。

サーバエクスプローラでパラメータを指定して正常にロードしましたが、エンティティモデル&に追加しました。生成するコードには入力パラメータがありません。ここで

は、ストアドプロシージャ

CREATE PROCEDURE `GetViewableMenuNodes`(IN siteId INT, IN parentId INT, IN userName varchar(255)) 
BEGIN 
    select m.* 
    from menunode m 
    where m.siteid = siteId 
    and m.showinmenu = 1 
    and m.parentid = parentId 
    and m.viewername = userName; 
END 

だと、これは、このバグのエントリチェックアウトモデル

public global::System.Data.Objects.ObjectResult<MenuNode> GetViewableMenuNodes() 
{ 
    return base.ExecuteFunction<MenuNode>("GetViewableMenuNodes"); 
} 

答えて

2

によって生成されたコードである:あなたの運については申し訳ありません

http://bugs.mysql.com/bug.php?id=44985

を。クラブへようこそ。 MySQL Connector/.NET Entity FrameworkからMySQLのストアドプロシージャを適切にサポートしているかどうかはわかりません。スレッドの日付からわかるように、この機能を導入するには非常に遅い応答がありました。

4

これが役に立つとお考えの場合は、MySQL Connector/.NET Entity FrameworkプロバイダのMySQLでパラメータを使用してストアドプロシージャを操作するために私が使用するアプローチがあります。私はExecuteStoreQuery()を呼び出します。これにより、モデルのパラメータを使って手順をマッピングするという課題に対処する必要がなくなります。これは私たちのニーズに応えます。ここで

public IList<SearchResultsMember> SearchMembers(int memberID, string countryCode, string regionCode, string cityCode, float distanceKm, 
     int genderID, int ageMin, int ageMax, int offsetRowIndex, int maxRows) 
    { 


     MySqlParameter[] queryParams = new MySqlParameter[] { 
             new MySqlParameter("memberIDParam", memberID), 
             new MySqlParameter("countryCodeParam", countryCode), 
             new MySqlParameter("regionCodeParam", regionCode), 
             new MySqlParameter("cityCodeParam", cityCode), 
             new MySqlParameter("distanceKmParam", distanceKm), 
             new MySqlParameter("genderIDParam", genderID), 
             new MySqlParameter("ageMinParam", ageMin), 
             new MySqlParameter("ageMaxParam", ageMax), 
             new MySqlParameter("offsetRowIndexParam", offsetRowIndex), 
             new MySqlParameter("maxRowsParam", maxRows) 
            }; 

     StringBuilder sb = new StringBuilder(); 
     sb.Append("CALL search_members(@memberIDParam, @countryCodeParam, @regionCodeParam, @cityCodeParam, @distanceKmParam, @genderIDParam, @ageMinParam, @ageMaxParam, @offsetRowIndexParam, @maxRowsParam)"); 

     string commandText = sb.ToString(); 
     var results = _context.ExecuteStoreQuery<SearchResultsMember>(commandText, queryParams); 

     return results.ToList(); 
    } 
3

は、我々はDbContextにStoredProceduresを行うためにした少し拡張したものです:

public static List<T> ExecuteStoredProcedure<T>(this DbContext dbContext, string storedProcedureName, params object[] parameters) 
    { 
     string storedProcedureCommand = "CALL " + storedProcedureName + "("; 

     List<object> augmentedParameters = parameters.ToList(); 

     storedProcedureCommand = AddParametersToCommand(storedProcedureCommand, augmentedParameters); 

     storedProcedureCommand += ");"; 

     return dbContext.Database.SqlQuery<T>(storedProcedureCommand).ToList<T>(); 
    } 

    public static List<T> ExecuteStoredRecursiveProcedure<T>(this DbContext dbContext, string storedProcedureName, params object[] parameters) 
    { 
     string storedProcedureCommand = "SET max_sp_recursion_depth = " + maxRecursionCount + "; CALL " + storedProcedureName + "("; 

     List<object> augmentedParameters = parameters.ToList(); 

     storedProcedureCommand = AddParametersToCommand(storedProcedureCommand, augmentedParameters); 

     storedProcedureCommand += ");"; 

     return dbContext.Database.SqlQuery<T>(storedProcedureCommand).ToList<T>(); 
    } 

    private static string AddParametersToCommand(string storedProcedureCommand, List<object> augmentedParameters) 
    { 
     for (int i = 0; i < augmentedParameters.Count(); i++) 
     { 
      storedProcedureCommand = AddParameterToCommand(storedProcedureCommand, augmentedParameters, i); 
     } 
     return storedProcedureCommand; 
    } 

    private static string AddParameterToCommand(string storedProcedureCommand, List<object> augmentedParameters, int i) 
    { 
     if (augmentedParameters[i].GetType() == typeof(string)) 
     { 
      storedProcedureCommand += "'"; 
     } 

     storedProcedureCommand += (augmentedParameters[i].ToString()); 

     if (augmentedParameters[i].GetType() == typeof(string)) 
     { 
      storedProcedureCommand += "'"; 
     } 

     if (i < augmentedParameters.Count - 1) 
     { 
      storedProcedureCommand += ","; 
     } 

     return storedProcedureCommand; 
    } 
1

私はそれが同様にSQLインジェクションの問題を扱うことができるように、より安全な、このパラメータのアプローチが好きです。私はそれを次のように一般化しました:

public DbRawSqlQuery<T> ExecuteStoredProcedure<T>(string storedProcedureName, params object[] parameters) 
     {   string storedProcedureCommand = "CALL " + storedProcedureName + "("; 

      List<object> augmentedParameters = parameters.ToList(); 

      MySqlParameter[] queryParams; 
      storedProcedureCommand = AddParametersToCommand(storedProcedureCommand, augmentedParameters, out queryParams); 

      storedProcedureCommand += ");"; 



      return ((DbContext)this).Database.SqlQuery<T>(storedProcedureCommand, queryParams); 
     } 



     private string AddParametersToCommand(string storedProcedureCommand, List<object> augmentedParameters, out MySqlParameter[] queryParams) 
     { 
      string paramName = ""; 
      queryParams = new MySqlParameter[augmentedParameters.Count()]; 
      for (int i = 0; i < augmentedParameters.Count(); i++) 
      { 
       paramName = "p" + i; 
       queryParams[i] = new MySqlParameter(paramName,augmentedParameters[i]);         
       storedProcedureCommand += "@" + paramName; 

       if (i < augmentedParameters.Count - 1) 
       { 
        storedProcedureCommand += ","; 
       } 
      } 
      return storedProcedureCommand; 
     } 
1

また、mysqlデータベースを扱うときには最も重要なことに注意してください。ストアド・プロシージャのパラメータには常にテーブルの列名とは異なる名前を付けます。そうでない場合は、sp内のクエリで混在します。例えば

:ここ

CREATE PROCEDURE `authenticate_user`(
IN p_login_name varchar(50), 
IN p_password varchar(80) 
) 
BEGIN 

SELECT `user`.`user_id`, 
    `user`.`login_name`, 
    `user`.`password` 
from users 
where `login_name` = p_login_name 
and `password` = p_password; 

END 
1

はそれだけでいつもと同じ、あなたのデータモデルを生成し、ストアドプロシージャを含めることを忘れていけないVS2012とMySQLコネクタ6.8.3で作業してしまった私のコードのサンプルです。

このヘルプの誰かが欲しいです。

public static IList<MyClass> GetCustOrderHist(string someParameter) 
    { 
     IList<MyClass> data = ((IObjectContextAdapter)TestDashboardEntities).ObjectContext.ExecuteStoreQuery<MyClass>("CALL CustOrderHist({0});", someParameter).ToList(); 

     return data; 
    } 

    public class MyClass 
    { 
     public string ProductName { get; set; } 
     public int TOTAL { get; set; } 
    } 
0

私の解決策はストアドプロシージャです。私は役に立つと思う。

MovieDbEntities db = new MovieDbEntities(); 
int id = 2; 
var result = db.Movie.SqlQuery($"CALL SP_ReadMovie({id})").ToList();