如何将两个存储过程合并为一个方法并返回一个结果?

时间:2018-09-21 07:11:08

标签: c# stored-procedures

在代码中,我试图从SQL Server中获取所有数据,并且该方法用于以网格形式列出其工作卷的用户。我在这里的问题是如何调用/合并两个存储过程并返回一个结果,而我的方法正确吗?如果没有,请解释一下并告诉我正确的方法,以便将来我可以学习如何做。谢谢。

public IEnumerable<ApplicationUser> GetAllUsers()
{
    try
    {
        List<ApplicationUser> userList = new List<ApplicationUser>();

        using (SqlConnection con = new SqlConnection(connectionString))
        {
            SqlCommand cmd = new SqlCommand("sp_UsersReadAll", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            SqlCommand cmd2 = new SqlCommand("sp_GetUserRolls", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            con.Open();
            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                ApplicationUser apUser = new ApplicationUser();

                apUser.Id = Convert.ToString(reader["Id"]);
                apUser.UserName = reader["Username"].ToString();
                apUser.FirstName = reader["FirstName"].ToString();
                apUser.LastName = reader["LastName"].ToString();
                apUser.Email = reader["Email"].ToString();

                userList.Add(apUser);
            }

            con.Close();
        }

        return userList;
    }
    catch (Exception)
    {
        throw;
    }
}

3 个答案:

答案 0 :(得分:1)

您可以一次调用两个存储过程,然后使用数据SqlDataReader.NextResult()来读取另一个结果集:

public IEnumerable<ApplicationUser> GetAllUsers()
{
    try
    {
        List<ApplicationUser> userList = new List<ApplicationUser>();
        using (SqlConnection con = new SqlConnection(connectionString))
        {
            SqlCommand cmd = new SqlCommand(@"exec sp_UsersReadAll
                                              exec sp_GetUserRolls", con);
            cmd.CommandType = System.Data.CommandType.Text;

            con.Open();
            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                ApplicationUser apUser = new ApplicationUser();

                apUser.Id = Convert.ToString(reader["Id"]);
                apUser.UserName = reader["Username"].ToString();
                apUser.FirstName = reader["FirstName"].ToString();
                apUser.LastName = reader["LastName"].ToString();
                apUser.Email = reader["Email"].ToString();

                userList.Add(apUser);
            }

            reader.NextResult();

            while (reader.Read())
            {
                ApplicationUserRoll apUserRoll = new ApplicationUserRoll();

                apUserRoll.Id = Convert.ToString(reader["Id"]);
                apUserRoll.UserId = reader["UserId"].ToString();

                userList.Single(u => u.Id == apUserRoll.UserId).Rolls.Add(apUserRoll);
            }
            con.Close();
        }

        return userList;
    }
    catch (Exception)
    {
        throw;
    }
}

希望有帮助。

答案 1 :(得分:0)

可能有很多方法可以完成此任务。例如-

  1. 您可以创建一个新过程,该过程可以合并这两个过程的数据,并且您只能从代码中调用一个proc。

  2. 调用一个过程并保留用户列表,并将用户ID传递给秒过程以获取相应的角色。

如果您需要更多帮助,请共享ApplicationUser类的过程和属性的输出。

答案 2 :(得分:0)

类似的东西应该起作用(我正在考虑您想要唯一的ID)

    public IEnumerable<ApplicationUser> GetAllUsers()
    {
        try
        {
            ApplicationUser apUser;
            List<ApplicationUser> userList = new List<ApplicationUser>();

            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("sp_UsersReadAll", con);
                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                SqlCommand cmd2 = new SqlCommand("sp_GetUserRolls", con);
                cmd2.CommandType = System.Data.CommandType.StoredProcedure;

                con.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    apUser = new ApplicationUser();
                    apUser.Id = Convert.ToString(reader["Id"]);
                    apUser.UserName = reader["Username"].ToString();
                    apUser.FirstName = reader["FirstName"].ToString();
                    apUser.LastName = reader["LastName"].ToString();
                    apUser.Email = reader["Email"].ToString();
                    userList.Add(apUser);
                }

                // You can refactor this code in another method for don't have to write it both
                reader = cmd2.ExecuteReader();
                while (reader.Read())
                {
                    apUser = new ApplicationUser();
                    apUser.Id = Convert.ToString(reader["Id"]);

                    // If id doesn't exists, we can continue and add the item 
                    if(!userList.Exists(o=>o.Id==apUser.Id))
                    {
                        apUser.UserName = reader["Username"].ToString();
                        apUser.FirstName = reader["FirstName"].ToString();
                        apUser.LastName = reader["LastName"].ToString();
                        apUser.Email = reader["Email"].ToString();
                        userList.Add(apUser);
                    }
                }
                con.Close();
            }

            return userList;
        }
        catch (Exception)
        {
            // Actually it's like if you had not try / catch
            throw;
        }
    }

我只是向您展示方法,我没有优化代码。