0

我有一个 System.InvalidOperationException: Collection was modified 错误,你可以在这里看到控制台的输出。

这是我的代码,我删除了很多行,以便结构更易于阅读。

static public void searchCode2(Dictionary<string, string> MList)
    {

        using (SqlConnection connection3 = new SqlConnection(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
        {


            connection3.Open();
            SqlCommand command2 = new SqlCommand(null, connection3);

            var keysWithMatchingValues = MList.Where(p => Equals(p.Value, "0")).Select(p => p.Key);

            // ce for devrait macher, meme s'il y plusieurs requetes
            // Tthe fallowing line is where the error point out.
            foreach (var key in keysWithMatchingValues)
            {

                Console.WriteLine(" missing list");
                string[] motToCut = key.ToString().Split(' ');
                Dictionary<string, int> MoviesListMissing = new Dictionary<string, int>();
                Dictionary<string, string> MoviesListMissingCode = new Dictionary<string, string>();
                Dictionary<string, DateTime> MoviesListMissingDate = new Dictionary<string, DateTime>();


                //// on va chercher si un des elements du dico n'a pas été récupéré.
                command2.CommandText = "";
                int counter = 0;

                foreach (string word_cutted in motToCut)
                {
                    // on considere que les mots qui ont plus d'une lettre
                    if (word_cutted.Length > 1)
                    {

                        command2.CommandText += "select Code, Titre, Date from Data where Titre LIKE '%" + word_cutted + "%';";
                        counter++;
                        Console.WriteLine("word_cutted : {0} ", word_cutted);
                    }
                }

                command2.Prepare();  // Calling Prepare after having set the Commandtext and parameters.

                SqlDataReader reader2 = command2.ExecuteReader();


                try
                {



                    for (int i = 0; i < counter; i++)
                    {
                        //CODES
                    }
                    bool MoviesListMissingisEmpty = (MoviesListMissing.Count == 0);
                    if (!MoviesListMissingisEmpty)
                    {


                        //CODES
                    }

                    // liste le dictionnaire
                    foreach (string key2 in MList.Keys)
                    {
                        Console.WriteLine("Last version : {0}, {1} ", key2, MList[key2]);
                    }


                }
                catch (Exception e)
                {
                    //Console.WriteLine("{0} Exception caught.", e);
                    Console.WriteLine("Last version : {0}", e);
                }
                finally
                {
                    // Always call Close when done reading.
                    reader2.Close();

                }

            }

            connection3.Close();
            // THIS WON'T PRINT
            Console.WriteLine(" Avant var key in keysWithMatchingValues ");



        }


    }

出于某种原因,我放了什么

 connection3.Close();

不起作用,我无法弄清楚原因。在一些类似的主题中,据说使用了锁定功能,但我不知道在哪里。(我尝试了一些地方,但没有奏效)。

如果可能有帮助,这是完整的代码:

   static public void searchCode2(Dictionary<string, string> MList)
    {

        using (SqlConnection connection3 = new SqlConnection(ConfigurationManager.ConnectionStrings["DistriDBEntities2"].ConnectionString))
        {


            connection3.Open();
            SqlCommand command2 = new SqlCommand(null, connection3);

            DateTime today = DateTime.Now;
            bool pbBool = false;
            string motFinal = "";
            var keysWithMatchingValues = MList.Where(p => Equals(p.Value, "0")).Select(p => p.Key);
            //Where(p => p.Value == "a").Select(p => p.Key);

            // ce for devrait macher, meme s'il y plusieurs requetes

            foreach (var key in keysWithMatchingValues)
            {

                pbBool = true;
                Console.WriteLine(" missing list");
                //literaltest.Text += "<br/>" + motFinal + ", original: " + key + "<br/>";
                string[] motToCut = key.ToString().Split(' ');
                Dictionary<string, int> MoviesListMissing = new Dictionary<string, int>();
                Dictionary<string, string> MoviesListMissingCode = new Dictionary<string, string>();
                Dictionary<string, DateTime> MoviesListMissingDate = new Dictionary<string, DateTime>();


                //// on va chercher si un des elements du dico n'a pas été récupéré.
                command2.CommandText = "";
                int counter = 0;

                foreach (string word_cutted in motToCut)
                {
                    // on considere que les mots qui ont plus d'une lettre
                    if (word_cutted.Length > 1)
                    {

                        command2.CommandText += "select Code, Titre, Date from Data where Titre LIKE '%" + word_cutted + "%';";
                        counter++;
                        Console.WriteLine("word_cutted : {0} ", word_cutted);
                    }
                }

                command2.Prepare();  // Calling Prepare after having set the Commandtext and parameters.

                //literaltest.Text += "<br/> on rentre dans le try apres word_cutted : ";

                SqlDataReader reader2 = command2.ExecuteReader();


                try
                {


                    int resultCounter = 1;
                    bool resultUnique = false;
                    string bontitre = "";
                    for (int i = 0; i < counter; i++)
                    {
                        if (i == 0)
                        {
                            while (reader2.Read())
                            {
                                //literaltest.Text += "<br/> si i = 0 ";
                                if (reader2[1].ToString().Length > 0)
                                {
                                    if (!MoviesListMissing.ContainsKey(reader2[1].ToString()))
                                    {
                                        //literaltest.Text += "<br/> i = 0   mot  : " + reader2[0].ToString() + "," + reader2[1].ToString();
                                        MoviesListMissing.Add(reader2[1].ToString(), 0);
                                        MoviesListMissingCode.Add(reader2[1].ToString(), reader2[0].ToString());
                                        bontitre = reader2[1].ToString();
                                        resultCounter++;
                                        if (reader2[2].ToString().Length > 0)
                                        {
                                            DateTime dt = Convert.ToDateTime(reader2[2].ToString());
                                            //literaltest.Text += "<br/> date Conversion orginal:" + reader2[2].ToString() + " new : " + dt.ToString("dd/MM/yyyy");
                                            MoviesListMissingDate.Add(reader2[1].ToString(), dt);
                                        }
                                    }
                                }
                            }
                        }

                        else if (!resultUnique)
                        {
                            // on réinitialise le compteur
                            resultCounter = 1;
                            reader2.NextResult();
                            while (reader2.Read())
                            {
                                if (reader2[1].ToString().Length > 0)
                                {
                                    //literaltest.Text += "<br/> i :  " + i + " mot : " + reader2[0].ToString() + "," + reader2[1].ToString();
                                    if (!MoviesListMissing.ContainsKey(reader2[1].ToString()))
                                    {
                                        MoviesListMissing.Add(reader2[1].ToString(), 0);
                                        MoviesListMissingCode.Add(reader2[1].ToString(), reader2[0].ToString());
                                        MoviesListMissingDate.Add(reader2[1].ToString(), Convert.ToDateTime(reader2[2].ToString()));
                                        bontitre = reader2[1].ToString();
                                    }
                                    else
                                    {
                                        //on incremente le nombre de point.
                                        MoviesListMissing[reader2[1].ToString()] += 1;
                                        bontitre = reader2[1].ToString();
                                    }
                                    resultCounter++;
                                }
                            }
                        }
                        if (resultCounter == 2)
                        {
                            // si on a eu qu'un retour lors d'une requete pour un mot alors c'est la bonne
                            resultUnique = true;
                            Console.WriteLine("ResultUnique true");
                            //break;
                        }
                    }
                    bool MoviesListMissingisEmpty = (MoviesListMissing.Count == 0);
                    if (!MoviesListMissingisEmpty)
                    {
                        if (resultUnique == false)
                        {
                            // liste le dictionnaire
                            int keyMax = 0;
                            string trueKey = MoviesListMissing.Keys.First();
                            string falseKey = "";
                            bool unique = true;
                            // on regarde quel titre a le plus de point.
                            foreach (string cle in MoviesListMissing.Keys)
                            {
                                if (MoviesListMissing[cle] > keyMax)
                                {
                                    keyMax = MoviesListMissing[cle];
                                    trueKey = cle;
                                    unique = true;
                                    falseKey = "";
                                }
                                else if (MoviesListMissing[cle] == keyMax)
                                {
                                    unique = false;
                                    falseKey += cle + ", ";
                                }
                            }
                            Console.WriteLine("Le bon titre est : {0} ", trueKey);
                            Console.WriteLine("Le bon titre est unique ? : {0} falsekey: {1}", unique.ToString(), falseKey);
                            // si le nombre max est détenue par un seul titre
                            if (unique)
                            {
                                bontitre = trueKey;
                                // on rajoute le code
                                MList[key.ToString()] = MoviesListMissingCode[trueKey];
                            }
                            else
                            // on regarde la date
                            {

                                string[] CuttedByDate = falseKey.ToString().Split(' ');
                                DateTime bestDate = MoviesListMissingDate[CuttedByDate[0]];
                                bontitre = CuttedByDate[0];
                                foreach (string wordDate in CuttedByDate)
                                {
                                    if ((Math.Abs(today.Subtract(MoviesListMissingDate[CuttedByDate[0]]).Days)) < Math.Abs(today.Subtract(bestDate).Days))
                                    {
                                        bontitre = wordDate;
                                    }
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine("Le bon titre trouvé de maniere unique : {0} ", bontitre);
                            MList[key.ToString()] = MoviesListMissingCode[bontitre];
                        }
                    }

                    // liste le dictionnaire
                    foreach (string key2 in MList.Keys)
                    {
                        Console.WriteLine("Last version : {0}, {1} ", key2, MList[key2]);
                    }



                }
                catch (Exception e)
                {
                    //Console.WriteLine("{0} Exception caught.", e);
                    Console.WriteLine("Last version : {0}", e);
                }
                finally
                {
                    // Always call Close when done reading.
                    reader2.Close();

                }

            }

            connection3.Close();
            Console.WriteLine(" Avant var key in keysWithMatchingValues ");             

        }


    }
4

1 回答 1

2

好的,这就是问题所在 - 您MList在迭代基于它的惰性求值查询时正在修改:

MList[key.ToString()] = MoviesListMissingCode[bontitre];

MList[key.ToString()] = MoviesListMissingCode[trueKey];

你不被允许这样做。

解决此问题的最简单方法是将键/值对的副本作为查询的一部分。所以这:

var keysWithMatchingValues = MList.Where(p => Equals(p.Value, "0")).Select(p => p.Key);

可以变成:

var keysWithMatchingValues = MList.ToList()
                                  .Where(p => Equals(p.Value, "0"))
                                  .Select(p => p.Key);

虽然我个人会将其重写为:

var keysWithMatchingValues = MList.ToList()
                                  .Where(p => p.Value == "0")
                                  .Select(p => p.Key);

此时,您可以在MList迭代时进行修改keysWithMatchingValues,因为它们是分开的。

(我也会把这个庞大的方法分解成更小的方法。)

于 2013-07-31T07:02:38.917 回答