I have a DataGridView
where I am able to select some rows from it and insert it in another DataGridView
, deleting the ones from the original DataGridView
. To do that I will make some validations to see if there is an equal name file or something like that.
This is the code I am using in the transfer Button
:
foreach (DataGridViewRow dtrow2 in frm.dataGridView2.Rows)
{
con = new SqlConnection(cs.DBConn);
con.Open();
string querySelect = "SELECT FileName FROM SentRecycle WHERE FileName ='" + dtrow2.Cells[2].Value.ToString() + "'";
cmd = new SqlCommand(querySelect);
frm.ShowDataGridView();
cmd.Connection = con;
reader = cmd.ExecuteReader();
if (reader.Read() == true)
{
MessageBox.Show("This file already in use!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
if ((reader != null))
{
reader.Close();
}
return;
}
}
But I cannot delete it because when I put repeated file to test the application out it will always look for the first row and does not check the others. Do you have any idea how can I solve it?
The return
statement will cause the foreach
to stop after the first match.
Calling return
will exit the method that it is in, regardless of any loops that may be executing, and that is the cause of your problem here.
Also, some others remarks:
- The message does not say which file is in use.
- For a dozen files in use, a dozen popups would show.
- You do not need to create a new connection for every query, one is enough.
- Using SqlParameter
is better and safer than concatenating the filename into the query.
The result would look something like this:
public bool AreFilesInUse()
{
var FilesInUse = new List<string>();
con = new SqlConnection(cs.DBConn);
con.Open();
var sql = "SELECT FileName FROM SentRecycle WHERE FileName = @file";
cmd = new SqlCommand(sql);
cmd.Parameters.Add("@file", SqlDbType.NVarChar);
cmd.Connection = con;
foreach (DataGridViewRow dtrow2 in frm.dataGridView2.Rows)
{
var file = dtrow2.Cells[2].Value.ToString();
cmd.Parameters["@file"].Value = file;
// frm.ShowDataGridView(); // does not seem useful here, maybe before the loop
var reader = cmd.ExecuteReader();
if (reader.Read())
FilesInUse.Add(file); // remember file name
reader.Close();
}
bool foundAny = FilesInUse.Count > 0;
if (foundAny)
{
var files = string.Join("\r\n", FilesInUse);
MessageBox.Show("The following files are already in use:\r\n" + files, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
con.Close();
return foundAny;
}
}
that is because you dont let your code to check all rows in your foreach
loop. remove return
keyword and check other ones. if you need these file names in somewhere else, put them in a list or something like that. also check if file name is null or empty to handle exceptions. check this:
var fileNamelist = new List<string>();
foreach (DataGridViewRow dtrow2 in frm.dataGridView2.Rows)
{
con = new SqlConnection(cs.DBConn);
con.Open();
//if null or empty set it to a default value. here i set it to "".
var fileName = string.IsNullOrEmpty(dtrow2.Cells[2].Value.ToString())
? ""
: dtrow2.Cells[2].Value.ToString();
string querySelect = "SELECT FileName FROM SentRecycle WHERE FileName ='" + fileName + "'";
cmd = new SqlCommand(querySelect);
frm.ShowDataGridView();
cmd.Connection = con;
reader = cmd.ExecuteReader();
if (reader.Read() == true)
{
MessageBox.Show("This file already in use!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
fileNamelist.add(fileName);
if ((reader != null))
{
reader.Close();
}
//return; this will finish loop. so removed!
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.