代码之家  ›  专栏  ›  技术社区  ›  Glenn Slaven

使用带有mysql db的实体框架和模型设计器不会获取存储过程参数

  •  5
  • Glenn Slaven  · 技术社区  · 15 年前

    我有最新的MySQL连接器,允许您使用Visual Studio实体框架设计器。它工作得很好,但我刚添加了一个存储过程。

    服务器资源管理器用指定的参数很好地加载了它,但是我将它添加到实体模型中,它生成的代码没有任何输入参数。

    这是存储过程

    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");
    }
    
    7 回复  |  直到 8 年前
        1
  •  3
  •   MomentSurfer    13 年前

    查看此Bug条目:

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

    对你的运气感到抱歉。欢迎来到俱乐部。显然,从mysql connector/.net entity framework对mysql中的存储过程有适当的支持是不可用的。从线程中的日期可以看出,引入该特性的响应速度非常慢。

        2
  •  6
  •   MomentSurfer    13 年前

    如果您觉得这很有帮助,下面是我使用的方法,用于从mysql connector/.net实体框架提供程序使用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
  •  4
  •   TChadwick    11 年前

    下面是我们在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;
        }
    
        4
  •  2
  •   Tanveer Ali    10 年前

    我喜欢这个参数方法更安全,因为它也可以处理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;
            }
    
        5
  •  2
  •   Tanveer Ali    10 年前

    另外,在处理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
    
        6
  •  2
  •   harold gonzales    10 年前

    下面是我的代码的一个示例,它与vs2012和mysql connector 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; }
        }
    
        7
  •  1
  •   doxmo    8 年前

    调用存储过程是我的解决方案。我希望有用。

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