جستجوي پيشرفته در c#
فرض كنيد يك فرم جستجو داريم كه اطلاعات كاربران را از ديتابيس خوانده و داخل يك DataTable قرار مي دهد وبا استفاده از يك DataGridView آنها را به نمايش در مي آورد.
تا اينجا فرضيات مسئله بود يعني خودتان بايد تا اينجاي كار را انجام داده باشيد، كليات كاري كه مي خواهيم انجام دهيم به اين صورت است كه به فرم يك تكست باكس اضافه مي كنيم ومي خواهيم همزمان كه كاربر تايپ مي كند عمل جستجو انجام شود پس بايد كدها را داخل خاصيت TextChanged آن بنويسيم.
عمل جستجو را داخل يك كلاس مي نويسيم و در برنامه كلاس را فراخواني مي كنيم، پارامتر هايي كه بايد به تابع درون كلاس بفرستيم عبارتنداز:
-
نام DataTable
-
خاصيت Text مربوط به تكست باكس
-
يك آرايه رشته اي شامل نام ستونهايي كه مي خواهيم جستجو براساس آنها انجام شود.
توضيحات مسئله تا حدودي در بالا گفته شد حالا بريم سراغ كدنويسي ها، يك آرايه از نوع رشته تعريف مي كنيم:
string[] columnName = new string[20];
حال در قسمت لود برنامه نام ستونهايي از DataTable را كه مي خواهيم جستجو بر اساس آنها انجام شود به آرايه اضافه مي كنيم:
columnName[0] = dt.Columns[“Name”].ColumnName;
columnName[1] = dt.Columns[“Family”].ColumnName;
columnName[2] = dt.Columns[“idPerson”].ColumnName;
يك كلاس ايجاد مي كنيم و داخل آن يك تابع تعريف مي كنيم، اين تابع يك رشته برمي گرداند، پارامترهاي ورودي آن را هم كه در بالا گفتيم پس تعريف آن به اين صورت مي باشد:
public string resaultOfSearch1(DataTable rdt , string txt , string[] listColumn)
{
}
اين تابع يك رشته برمي گرداند كه دستور فيلتر كردن DataTable در آن نوشته شده است، به علت حجم نسبتا زياد كدهاي اين تابع فقط يك توضيح كلي درباره آن ارائه مي گردد:
ابتدا چك مي كند كه آيا txt خالي است يا نه
if (txt != “”)
{
}
اگر خالي بود كه كاري انجام نمي دهد و رشته را خالي برمي گرداند در غير اين صورت سعي(دستور Try) مي كند رشته را به عدد تبديل كند اگر توانست يعني يا عدد بوده ويا رشته عددي ولي اگر نتوانست(دستور catch) صد در صد رشته مي باشد البته در اين مثال چون داده هاي ما فقط از دو نوع int و string مي باشند.
if (txt != “”)
{
try
{
int x = Convert.ToInt32(txt);
items = string.Empty;
}
catch (Exception)
{
}
}
اگر txt عدد يا رشته عددي باشد نوع آنرا بررسي مي كند چون اگر عدد باشد از عبارت = در txt استفاده مي كنيم و اگر رشته باشد از دستور LIKE .
دستورات داخل Try :
try
{
int x = Convert.ToInt32(txt);
items = string.Empty;
for (int i = 0; i < rdt.Columns.Count; i++)
{
if (Array.IndexOf(listColumn, rdt.Columns[i].ToString()) != -1)
{
if (rdt.Columns[i].DataType == typeof(Int32))
{
if (i == rdt.Columns.Count – 1)
{
items += rdt.Columns[i] + “=” + txt;
}
else
{
items += rdt.Columns[i] + “=” + txt + ” OR “;
}
}
else if (rdt.Columns[i].DataType == typeof(string))
{
if (i == rdt.Columns.Count – 1)
{
items += rdt.Columns[i] + ” LIKE ‘%” + txt + “%'”;
}
else
{
items += rdt.Columns[i] + ” LIKE ‘%” + txt + “%'” + ” OR “;
}
}
}
}
}
دستورات داخل Catch :
catch (Exception)
{
try
{
items = string.Empty;
for (int i = 0; i < rdt.Columns.Count; i++)
{
if (Array.IndexOf(listColumn, rdt.Columns[i].ToString()) != -1)
{
if (rdt.Columns[i].DataType == typeof(string))
{
if (i == rdt.Columns.Count)
{
items += rdt.Columns[i] + ” LIKE ‘%” + txt + “%'”;
}
else
{
items += rdt.Columns[i] + ” LIKE ‘%” + txt + “%'” + ” OR “;
}
}
}
}
}
catch (Exception)
{
}
}
در آخر ممكن است انتهاي رشته يك عبارت OR اضافي داشته باشيم اگر بود آن را حذف مي كنيم و بعد رشته را به عنوان خروجي Return مي كنيم.
حال در برنامه در قسمت مربوط به TextChanged تكست باكس يك شي از كلاس ساخته و تابع را فراخواني مي كنيم خروجي اين تابع يك رشته است كه از آن براي عمليات فيلترينگ DataTable استفاده مي شود:
private void textBox4_TextChanged(object sender, EventArgs e)
{
Class.search1 srch1 = new Class.search1();
dt.DefaultView.RowFilter = srch1.resaultOfSearch1(dt,textBox4.Text,columnName);
}
همه كد هاي بالا در قالب يك پروژه با زبان visualStudio 2010 همراه با فايل هاي ديتابيس(sql2008) در لينك زير قرار دارند.