DataTable未保留添加的行

时间:2016-05-19 15:32:28

标签: c# asp.net gridview datatable

此网页应如下:

调用populateTeamMembers(),它首先检查数据表是否没有行(表明这是第一次调用该函数),以防它查询SQL以查看谁是现有团队成员,加载进入数据表sqlTeamMembers

此函数还检查第二个数据表newTeamMembers中是否有任何行,如果是,则将newTeamMembers的内容合并到sqlTeamMembers中。第一次加载页面时,newTeamMembers数据表应始终为空,因此不会执行合并。

最后,既然sqlTeamMembers应该包含我们需要的每个人,它会将它绑定到gridview以显示在网页上。

显示后,网格视图下方会显示一个下拉列表,其中包含可添加到团队中的员工列表。如果在ddl上更改了所选索引,则会收到回发并调用selectedIndexChanged()。

selectedIndexChanged()中的逻辑是它将选定的个人信息查询到数据表中,如果用户已经分配给不同的团队,则警告用户,并继续将员工添加到newTeamMembers数据表中。

最后,再次调用populateTeamMembers(),这次newTeamMembers数据表中有数据,并且在再次绑定到gridView之前执行合并。

由于两个数据表sqlTeamMembers和newTeamMembers的性质,我已经在我的班级头部初始化它们,因此所有函数都可以访问它们。

它可以为sqlTeamMembers添加一个新行,但如果我尝试继续第二次添加,它就会消除第一个添加。 由于某种原因,newTeamMembers没有保留新行,它只包含selectedIndexChanged()创建的最新添加。

每次调用selectedIndexChanged()时,如何让newTeamMembers保留新行?

public partial class Personnel_Admin_Teams : System.Web.UI.Page
{

SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["WebServerConnectionString"].ConnectionString);
SqlDataReader myreader = default(SqlDataReader);
SqlCommand cmd = new SqlCommand();


string sqlStr;
DataTable sqlTeamMembers = new DataTable();
DataTable newTeamMembers = new DataTable();
...



protected void populateTeamMembers(string TeamID)
{
    if (sqlTeamMembers.Rows.Count == 0)
    {
        /***  Read Team Members with Matching TeamID from Employees Table ***/
        cnn.Open();
        sqlStr = "SELECT [ID], [LastName]+', '+[FirstName] AS [Name], ISNULL([TeamRole], '') AS [TeamRole] FROM [Employees] WHERE [TeamID] = " + TeamID + ";";
        cmd = new SqlCommand(sqlStr, cnn);
        sqlTeamMembers.Load(cmd.ExecuteReader());
        cnn.Close();
    }



    if (newTeamMembers.Rows.Count > 0)
    {
        sqlTeamMembers.Merge(newTeamMembers);
    }

    gvTeamMembers.DataSource = sqlTeamMembers;
    gvTeamMembers.DataBind();


    try
    {
        for (int i = 0; i < gvTeamMembers.Rows.Count; i++)
        {

            DropDownList ddlTeamRole = gvTeamMembers.Rows[i].Cells[2].FindControl("ddlTeamRole") as DropDownList;
            string txtTeamRole = sqlTeamMembers.Rows[i][2].ToString();
            txtTeamRole = txtTeamRole.Replace("'", "''");

            ddlTeamRole.SelectedValue = txtTeamRole;
        }
    }

    catch (Exception ex)
    {
        ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "class", "alert(\"There was an error: " + ex + "\");", true);
    }
}



selectedIndexChanged()  
{    


        cnn.Open();
        sqlStr = "SELECT [ID], [LastName]+', '+[FirstName] AS [Name], ISNULL([TeamRole], '') AS [TeamRole], ISNULL([TeamID], '0') FROM [Employees] WHERE [ID] = " + ddlAllEmployees.SelectedValue + ";";
        cmd = new SqlCommand(sqlStr, cnn);
        DataTable addOneMember = new DataTable();
        addOneMember.Load(cmd.ExecuteReader());
        cnn.Close();


        int empTeamID = Convert.ToInt32(addOneMember.Rows[0][3]);

        /*** If DT has not been used yet, establish columns ***/
        if (newTeamMembers.Columns.Count == 0)
        {
            newTeamMembers.Columns.Add("ID", typeof(int));
            newTeamMembers.Columns.Add("Name", typeof(string));
            newTeamMembers.Columns.Add("TeamRole", typeof(string));
        }

        /*** Remove TeamID Column before merging data back to primary DataTable, perform merge ***/
        addOneMember.Columns.RemoveAt(3);
        newTeamMembers.Merge(addOneMember);



    if (empTeamID != 0)
        {
            sqlStr = "SELECT [TeamLocation]+' | '+[Department]+' | '+[Type]+' | '+[Team]+' | '+[Shift] AS [Team] FROM [Teams] WHERE [ID] =" + empTeamID + ";";
            cmd = new SqlCommand(sqlStr, cnn);
            cnn.Open();
            myreader = cmd.ExecuteReader();
            myreader.Read();

            string existingTeam = myreader[0].ToString();

            myreader.Close();
            cnn.Close();

            ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "class", "alert(\"Warning: User is currently assigned to another team.  Employee will be removed from " + existingTeam + " when you save this page.\");", true);

        }
    }

2 个答案:

答案 0 :(得分:1)

您需要了解一些事项。

网页是无状态的,这意味着它的初始传递和后续的PostBacks,你负责通过一些持久性媒介保存和恢复状态。

许多服务器控件可以为您执行此操作,但您选择通过DataTables管理所有这些,因此您需要实现数据持久性。对于数据库查询结果,SqlDataSource控件使用应用程序缓存。您应该以编程方式使用它:

    public partial class Personnel_Admin_Teams : System.Web.UI.Page
    {
      DataTable sqlTeamMembers = null;
      DataTable newTeamMembers = null;

      protected void Page_Load( object sender, EventArgs e ) {
        if( !Page.IsPostBack ){
          if( Application.Cache["sqlTeamMembers"] == null ) 
            Application.Cache["sqlTeamMembers"] = new DataTable();

          if( Application.Cache["newTeamMembers"] == null ) 
            Application.Cache["newTeamMembers"] = new DataTable();
        }

        sqlTeamMembers = (DataTable) Application.Cache["sqlTeamMembers"];
        newTeamMembers = (DataTable) Application.Cache["newTeamMembers"];

        // NOTE: sqlTeamMembers will be null until you make that call to 
        //       populateTeamMembers()  so there is no hard and fast rule 
        //       about binding during PageLoad.  Bind every time you need 
        //       to reflect changes.
        gvTeamMembers.DataSource = sqlTeamMembers;
        gvTeamMembers.DataBind();
      }

    }

另外,只是为了验证,DataTables不是实时的,打开了与数据库的连接。对DataTable的更改不会自动写回您的数据库。您必须进行适当的INSERT / UPDATE SQL调用。

答案 1 :(得分:0)

我认为问题在于这一行的位置:

DataTable newTeamMembers = new DataTable();

由于它在课程开始时,每次加载页面时都会运行,这意味着每次您加载页面,包括页面是回发时。例如,当用户单击按钮添加新的团队成员时,就会发生回发。然后将该页面发回服务器,并包含用户条目。

您正在寻找的行为是初始化新的newTeamMembers 第一次页面加载,但当页面是回发时。要解决此问题,请在类的顶部声明newTeamMembers,但仅在页面不是回发时初始化它,方法是在页面加载事件中检查:

public partial class Personnel_Admin_Teams : System.Web.UI.Page
{
    DataTable newTeamMembers;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) //page is loaded for the first time
        {
            newTeamMembers = new DataTable();
        }
    }
    //rest of the code
}