PDA

View Full Version : سوال: معاينه ي كد و فرم جستجو ام!



hobab1987
پنج شنبه 01 مهر 1389, 21:25 عصر
اين كد مربوطه جستجوي هر بخش مي باشد:
متأسفانه تعداد فيلدها زياده و براي جستجو دچار مشكل شدم.
از طرفي تعداد بخش ها(جدولها) ابتدا بايد انتخاب بشه براي جستجو .
و چيزي كه هم براي بررسي تكست باكس پر بين فيلدها OR به كار بردم كه البته اين كد خلاصه شده وگرنه از اين وحشت ناكتره!


try
{
SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=Xadamat;Integrated Security=True");
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
if (comboBox1.Text == "انتخاب شود")
{
MessageBox.Show("لطفاً بخش مورد نظر را انتخاب كنيد", "اخطار", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
switch (comboBox1.Text)
{
case "اطلاعات وام":
cmd.CommandText = "SELECT اشخـــاص.ID,اشخـــاص.Dossier_Num, شخـــاص.Lname,اشخـــاص.Fname,اش ـــاص.Identity_Num,اشخـــاص.Father, شخـــاص.Status,اشخـــاص.Recruitmen t_Date,اشخـــاص.Pensioner_Date,اشخــ اص.Description,وام.Loan_Type,وام.Loan_Cos t,وام.Division_Cost,وام.Division_Num,وام. Request_Date,وام.Done_Date FROM اشخـــاص INNER JOIN وام ON ((اشخـــاص.ID=وام.ID_Person) AND (اشخـــاص.ID=@A OR (وام.RQdate BETWEEN @J AND @K)))";
break;
case "اطلاعات ضيافت":
if (radioButton1.Checked == true)
cmd.CommandText = "SELECT افرادضيافت.ID_Repast,اشخـــاص.ID ,اشخـــاص.Dossier_Num,اشخـــاص.Lna me,اشخـــاص.Fname,اشخـــاص.Identit y_Num,اشخـــاص.Father,اشخـــاص.Sta tus,اشخـــاص.Recruitment_Date,اشخـــ اص.Pensioner_Date,اشخـــاص.Description FROM اشخـــاص INNER JOIN افرادضيافت ON اشخـــاص.ID=افرادضيافت.ID_Person AND افرادضيافت.ID_Repast=@C OR اشخـــاص.Fname=@E OR اشخـــاص.Lname=@F OR اشخـــاص.Identity_Num=@G OR اشخـــاص.Father=@H OR اشخـــاص.Status=@I";
else if (radioButton2.Checked == true)
cmd.CommandText = "SELECT *FROM ضيافت";
break;
}
}

cmd.Parameters.AddWithValue("@A", Convert.ToString(textBox1.Text));
cmd.Parameters.AddWithValue("@C", Convert.ToString(textBox2.Text));
cmd.Parameters.AddWithValue("@E", textBox4.Text);
cmd.Parameters.AddWithValue("@F", textBox5.Text);
cmd.Parameters.AddWithValue("@G", textBox6.Text);
cmd.Parameters.AddWithValue("@H", textBox7.Text);
cmd.Parameters.AddWithValue("@I", comboBox2.Text);
cmd.Parameters.AddWithValue("@J", Convert.ToInt64(comboBox3.Text + comboBox4.Text + comboBox5.Text));
cmd.Parameters.AddWithValue("@K", Convert.ToInt64(comboBox6.Text + comboBox7.Text + comboBox8.Text));
da.SelectCommand = new SqlCommand();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
cn.Open();
da.Fill(ds, "T_Inf");
cn.Close();
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "T_Inf";
}
catch
{
}
و اينم فرم ام هست:
http://up.iranblog.com/Files/814e216e23c14ed9987d.PNG

mehdi.mousavi
پنج شنبه 01 مهر 1389, 23:07 عصر
سلام.
این کد شما پر از ایراده:


ConnectionString رو نباید اینطوری توی برنامه Hard Code کنید. بجای اینکار باید اونو در فایل config یکبار تعیین کرده و از اون پس اونو آدرس کنید.
نبستن Connection ها پس از پایان کار، باعث میشه تا از Connection Pooling در ADO.NET بخوبی بهره برده نشه و این رو Performance برنامه تاثیر میذاره.
Validate کردن User Entry باید در جایگاه مناسبی (http://msdn.microsoft.com/en-us/library/ms229603.aspx) انجام بشه.
اسامی استفاده شده برای متغیرها اصلا صحیح نیست. اسامی باید معنا دار باشه (http://barnamenevis.org/forum/showthread.php?t=224704). radioButton1 هیچ اطلاعاتی در مورد اون radio button به من نمیده.
اسامی استفاده شده بعنوان نام جداول در بانک مطلقا نباید فارسی باشه. من بارها این چنین کدهای وحشتناکی رو دیده ام، که حقیقتا آزار دهنده هستش. لطفا به اصول و قواعد نامگذاری در بخشهای مختلف توسعه نرم افزار پایبند باشید.
شما نباید کدهای بخشهای مختلف رو با هم ترکیب کنید. در این تابع، کد UI، DAL، Facade و ... همگی با هم ترکیب شده و این معجون وحشتناک رو ایجاد کرده. برای خوانایی و امکان استفاده مجدد، کدهاتون رو Refactor کنید.
استفاده از Dynamic SQL ها واقعا خطرناکه، ضمن اینکه، بسته به شرایط، میتونه روی Compile اون Statement و Cache کردنش در RDBMS تاثیر بذاره. روش صحبح، فراخوانی Stored Procedure های متفاوت (با پارامترهای مورد نیاز) در Branch های مختلف کد هستش. به بیان دیگه، وقتی متوجه شدید که باید اطلاعات ضیافت رو بگیرید، میتونید یک متود GetHospitality ایجاد کنید و با ارسال پارامترهای مورد نظر به این تابع، اطلاعات ضیافت رو بر اساس Formal Parameter های این تابع در Business Object های مورد نظرتون دریافت کنید.
متود Convert.ToInt64 رو قبل از اینکه ورودی تابع رو برای Valid بودن بررسی کنید، فراخوانی کرده اید. استفاده از اطلاعات وارد شده توسط کاربر قبل از بررسی اعتبار اونها، اولین نقیصه امنیتی در برنامه ها محسوب میشه.
عمل Catch کردن Exception ها بدین شکلی که شما انجام داده اید، بسیار بسیار خطرناکتر از اون چیزی هستش که تصورش رو می کنید. برای اطلاعات بیشتر، در پستهای ارسالی من دنبال Corrupted State Exception یا CSE بگردید و نوشته های من در این مورد رو مطالعه کنید.
هدف از این عبارت چیه؟ Convert.ToString(textBox1.Text) اینجا textBox1.Text خودش string هستش، شما برای چی این تبدیل (؟) رو انجام میدید؟

اینها رو گفتم که بگم، مشکل کد شما، یافتن روشی برای نوشتن SQL مورد نظرتون به روش دیگه نیستش. مسائلی که نام بردم، بسیار بسیار مهم تر از منطق مورد استفاده شما در این تابع هستش. اما در هر حال، برای اینکه کد بهتری بنویسید، میتونید کلیه شرایط جستجو رو در یک Dictionary حاوی کلیدی برای نام فیلد و مقدار هر فیلد (بعنوان Value ی این Dictionary) داشته باشید، سپس در یک Loop اون Dynamic SQL رو ایجاد کرده و Execute کنید. اما باز هم میگم، جای اینکه اینکارو کنید، اون 10 موردی که نام بردم رو روش کار کنید تا کدتون فقط یک ایراد داشته باشه.

موفق باشید.