as the title say's I am attempting to get to edit a list item inside of a foreach loop. I know it is not possible, so I am asking for solutions to work around this.
As this is taking data directly from a MySQL server, it need's to be done inside of this loop and with the correct indexes. I attempted to use a second list and change the data outside of the foreach loop, but that did not account for the index positions of the items.
foreach (string friend in friendsOnline)
{
query = "SELECT `username` FROM `accounts` WHERE email = '" + friend + "'";
cmd = new MySqlCommand(query, conn);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
for (int i = 0; i<friendsOnline.Count; i++)
{
if (friendsOnline[i].Contains(friend))
{
friendsOnline[i] = rdr[0].ToString();
}
}
}
}
-
What exactly are you trying to achieve? Why not use a for-loop instead of foreach?Steeeve– Steeeve2021年11月13日 20:06:42 +00:00Commented Nov 13, 2021 at 20:06
-
Holy sql injection vulnerability, Batman.Joel Coehoorn– Joel Coehoorn2021年11月13日 22:26:49 +00:00Commented Nov 13, 2021 at 22:26
-
@JoelCoehoorn To be honest, I'm not really bothered if user's decide to add a random email address to their friend's list.Luke– Luke2021年11月13日 23:30:19 +00:00Commented Nov 13, 2021 at 23:30
-
@Luke You can use this to do a lot more than just add random emails addresses... for example, I could absolutely use the exact code in your question to drop every table your database.Joel Coehoorn– Joel Coehoorn2021年11月15日 14:50:22 +00:00Commented Nov 15, 2021 at 14:50
1 Answer 1
As I can see, you have emails in the friendsOnline:
string[] friendsOnline = new[] {
"[email protected]",
"[email protected]",
};
and you want to change these emails into names:
string[] friendsOnline = new[] {
"Frodo Baggins",
"Sauron the Black",
};
First of all, I suggest executing query just once: SQL is too slow to be run in a loop; instead you can build a dictionary which eMail corresponds to which indexes:
using System.Linq;
...
// eMail - indexes correspondence
Dictionary<string, int[]> dict = friendsOnline
.Select((name, index) => (name : name, index : index))
.GroupBy(pair => pair.name, pair => pair.index, StringComparer.OrdinalIgnoreCase)
.ToDictionary(group => group.Key, group => group.ToArray());
// We take all users (no WHERE), but once
// We read both username and email
string sql =
@"SELECT `username`,
`email`
FROM `accounts`";
//DONE: using - we should Dispose IDisposable Command and Reader
using cmd = new MySqlCommand(sql, conn);
using rdr = cmd.ExecuteReader();
while (rdr.Read()) {
string name = Convert.ToString(rdr[0]);
string mail = Convert.ToString(rdr[1]);
// If we have correspondent indexes, we change friendsOnline
if (dict.TryGetValue(mail, out var indexes))
foreach (var index in indexes)
friendsOnline[index] = name;
}
7 Comments
email is a field of account query. I've rewritten the query: I've dropped WHERE but add email to SELECT. Note, that now query have 2 fields, that's why rdr[1] exists (and equals to email)