我有两个列表,两个列表都包含代表各自团队中玩家评分的整数。
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();
}
有没有办法避免这种情况并添加评级而不重叠?
注意:代码在这里只是作为我正在做的事情的一个例子,你不必阅读它来了解我正在尝试做什么,但它可能会或可能不会帮助你理解。
答案 0 :(得分:0)
我认为您的问题在于信息重复,并且信息位于每个列表的相同位置。如果你在SQL插入之间断开,并查询数据库以查看数据,我希望你会发现你的where子句在两个插入上对该特定播放器的评估为真。
关于要对其进行哪些编辑,我建议将您的玩家列表分为列表,一个用于团队1,另一个用于团队2,并且仅在团队1列表上运行团队1的更新查询,对于团队2也一样。
一些注意事项..在上面列出的代码中,你有很多整数分裂错误的机会,或者让1个团队的玩家转移到另一个团队。我无法准确地为您提供一段代码来修复您的问题,而无需重写代码片段的重要部分。我还建议您完全构建数据库行条目并一次插入所有条目,而不是插入,然后返回并更新。它在数据库上添加了不必要的负载,并引入了另一层可能的错误。
我对代码的理解如下:
以下可能是一种方法,可以避免许多可能的错误来源。
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)按评级排序,然后您不必担心跟踪分配给谁的值。