C#数据库更新重叠

时间:2016-02-16 18:15:52

标签: c# sql list ms-access

我有两个列表,两个列表都包含代表各自团队中玩家评分的整数。

Ex:
team1ListOfRatings: 9,1,4
team2ListOfRatings: 6,2,4

我希望将这些输入到我拥有的访问数据库中。但是,当我尝试输入它们时,如果列表中的数字有任何相似之处(在上面显示的例子中,这是'4'),那么第一个列表中的重复评级将被分配给数据库中的团队2 。

它会产生这样的结果:

Players in team 1: Ben (rating 9), Will(rating 1) 
Players in team 2: Philip(rating 6), Sam(rating 2), Bert(rating 4), Gary(rating 4)

从上面的示例中可以看出,很明显Gary需要在第一个团队中,但是因为我使用了for循环,它会将任何重复项重新分配给最近for循环中使用的团队。 这是我用于此的代码:

// this adds the players to the database temporarily without a team
for (int i = 0; i < numberOfPlayers; i++)
{
    OleDbConnection connection = new OleDbConnection(CONNECTION STRING HERE);

    OleDbCommand command = new OleDbCommand();

    connection.Open();
    command.Parameters.Add("@name", OleDbType.VarWChar).Value = textBox[i].Text;
    command.Parameters.Add("@rating", OleDbType.Integer).Value = Convert.ToInt32(ratingBox[i].Text);
    command.CommandText = "INSERT INTO TotalPlayerName ([PlayerName], [Team], [Rating],  [Substitute], [Complete], [SportID]) VALUES (@name, null , @rating,  false, false, " + ID + ")";
    command.CommandType = CommandType.Text;
    command.Connection = connection;

    command.ExecuteNonQuery();
    connection.Close();
}


            //list of all ratings:

            List<int> ratingList = new List<int>();

            for (int i = 0; i < numberOfPlayers; i++)
            {
                ratingList.Add(Convert.ToInt32(ratingBox[i].Text));
            }
            ratingList.Sort();
            var count = ratingList.Count();

            // if even number of players, keep aside the one in the middle (as rating)
            int? middle = null;
            if (count % 2 != 0)
            {
                middle = ratingList[count / 2];
                ratingList.RemoveAt(count / 2);
            }

            var ratingListDesc = ratingList.OrderByDescending(i => i).ToList();

            var half = count / 2;
            var take = half % 2 != 0 ? half - 1 : half;

            var team1List = ratingList.Take(take).Where((r, i) => i % 2 == 0).ToList();
            team1List.AddRange(ratingListDesc.Take(take).Where((r, i) => i % 2 == 0));

            var team2List = ratingList.Take(take).Where((r, i) => i % 2 != 0).ToList();
            team2List.AddRange(ratingListDesc.Take(take).Where((r, i) => i % 2 != 0));

            // we just have to redistribute the remaining pair between each team
            if (half % 2 != 0)
            {
                team1List.Add(ratingList[half - 1]);
                team2List.Add(ratingListDesc[half - 1]);
            }

            // this part will add the team numbers to the database
            for (int i = 0; i < (count/2); i++)
            {
                OleDbConnection connection = new OleDbConnection(CONNECTION STRING HERE);

                OleDbCommand command = new OleDbCommand();

                connection.Open();
                command.CommandText = "update TotalPlayerName set Team = 1, Complete = true WHERE Team = null AND Complete = false AND Rating = " + team1List[i];
                command.CommandType = CommandType.Text;
                command.Connection = connection;

                command.ExecuteScalar();
                command.CommandText = "update TotalPlayerName set Team = 2, Complete = true WHERE Team = null AND Complete = false AND Rating = " + team2List[i];
                command.ExecuteScalar();
                connection.Close();


            }

有没有办法避免这种情况并添加评级而不重叠?

注意:代码在这里只是作为我正在做的事情的一个例子,你不必阅读它来了解我正在尝试做什么,但它可能会或可能不会帮助你理解。

1 个答案:

答案 0 :(得分:0)

我认为您的问题在于信息重复,并且信息位于每个列表的相同位置。如果你在SQL插入之间断开,并查询数据库以查看数据,我希望你会发现你的where子句在两个插入上对该特定播放器的评估为真。

关于要对其进行哪些编辑,我建议将您的玩家列表分为列表,一个用于团队1,另一个用于团队2,并且仅在团队1列表上运行团队1的更新查询,对于团队2也一样。

一些注意事项..在上面列出的代码中,你有很多整数分裂错误的机会,或者让1个团队的玩家转移到另一个团队。我无法准确地为您提供一段代码来修复您的问题,而无需重写代码片段的重要部分。我还建议您完全构建数据库行条目并一次插入所有条目,而不是插入,然后返回并更新。它在数据库上添加了不必要的负载,并引入了另一层可能的错误。

我对代码的理解如下:

  1. 结合玩家评分
  2. 如果是奇数玩家,请删除中等评级
  3. 将球员分为最高评价团队1,第二等级评分团队2,第三等级评分团队等等。
  4. 将数据保存到数据库。
  5. 以下可能是一种方法,可以避免许多可能的错误来源。

    List<int> ratingsList = new List<int>(); //Presume this is already populated.
    List<int> team1 = new List<int>();
    List<int> team2 = new List<int>();
    
    ratingsList = ratingsList.Sort();
    
    if(ratingsList.Count() % 2 != 0)
    {
        ratingsList.Remove((ratingsList.Count()/2)+2));  //Integer divide intentional
    }
    
    for(int i = 0; i < ratingsList.Count() ; i++)
    {
        if(i%2 != 0)
        {
            team1.Add(ratingsList[i]);
        }
        else
        {
            team2.Add(ratingsList[i]);
        }
    }
    
    foreach(var player in team1)
    {
        //Add SQL Insert here
    }
    foreach(var player in team2)
    {
        //Add SQL Insert here
    }
    

    上面列出的代码段是伪代码,所以不要指望它只是工作。我看到的最大的问题是,玩家正在被评级划分和识别,这不是单个玩家所独有的,因此您无法在代码中唯一识别玩家。超出问题范围的建议是构建一个包含信息的播放器类,并制作类型为Player的ratingsList,team1,team2。您仍然可以使用OrderByDesc(linq)按评级排序,然后您不必担心跟踪分配给谁的值。