PDA

View Full Version : مشکل با کلاس SqlCommandbuilder



csharp.net
پنج شنبه 25 شهریور 1395, 11:28 صبح
سلام دوستان
به کد زیر توجه کنید :


private void button1_Click(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection();
connection.ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;"
+ @"AttachDbFilename=|DataDirectory|\University.mdf;"
+ "Integrated Security=True;"
+ "Connect Timeout=30";

SqlCommand command = new SqlCommand();
command.CommandText = "SELECT * FROM Students";
command.Connection = connection;

DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.Fill(dataset, "Students");

DataRow row = dataset.Tables["Students"].NewRow();
row["FirstName"] = firstNameTextBox.Text;
row["LastName"] = lastNameTextBox.Text;
row["Gender"] = genderTextBox.Text;
row["Age"] = Int32.Parse(ageTextBox.Text);
row["Address"] = addressTextBox.Text;

dataset.Tables["Students"].Rows.Add(row);

try
{
int result = adapter.Update(dataset, "Students");

if (result > 0)
MessageBox.Show("Success!");
else
MessageBox.Show("Failed!");
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}


کد بالا مربوط به اضافه کردن یک رکورد به بانک اطلاعاتی هس و درست کار می کنه. مشکل من اینه که دقیقا کاربرد کلاس SqlCommandbuilder رو متوجه نشدم. جایی خوندم که این کلاس به طور خودکار دستوارت ثبت و حذف و ویرایش رو تولید میکنه. حالا سوال بنده در باره کد بالا :
این کلاس تو کد بالا از کجا میدونه که باید کد ثبت رو تولید کنه در حالیکه کدی کلاس Command یه دستور Select ه. اصلا کلا گیج شدم. چرا باید دستور سلکت بنویسیم و اونو بدیم به dataadapter و بعد اونو بدیم به SqlCommandbuilder ؟

ali_md110
جمعه 26 شهریور 1395, 13:01 عصر
توسط متد fill شی adapter کوئری Select که بر روی بانک اجرا شده روو میریزید درون دیتاست
و در این لحظه اسکیمای و شکل و شمایل جدولتون منظورم فیلدها و سایر اشیاء اون شکل میگیره
یعنی شما باید یک دستور Select بنویسید تا فیلدها شناسایی بشن و دیتاست متوجه بشه جدولتون چه شکلی هست چند تا فیلد داره و غیره
و اینکه چگونه متوجه میشه اینه که هر وقت تغییری در دیتاست میدید مثلا رکورد اضافه می کنید


dataset.Tables["Students"].Rows.Add(row);

از طریق یک event بنام RowUpdating تغییرات دیتاست به اطلاع dataadapter رسانده و اون هم تحویل SqlCommandbuilder میده تا بستگی به نوع فلگ تغییر یافته عملیات CRUD انجام بگیره
در اینجا دیتااداپتور تحویل SqlCommndBuilder شده


SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

csharp.net
جمعه 26 شهریور 1395, 14:38 عصر
بسیار ممنون از توضیحات کامل و دقیقتون، ... دو سوال :

1- آیا خط 16 کد بالا بعد از خط 26 اجرا میشه یا بعد از خط 40 یعنی بعد از دستور try catch؟

2- آیا دستور تولید شده توسط این کلاس به بانک اصلی اعمال میشه؟

mrprestige
جمعه 26 شهریور 1395, 17:15 عصر
عرض سلام و احترام خدمت شما دوست عزیز ، با کسب اجازه از دوست بزرگوار جناب ali_md110 (http://barnamenevis.org/member.php?18325-ali_md110) در پاسخ سوال اولتون دوست من باید عرض کنم در خط 16 اینجا پارامتری که بهش پاس داده میشه همون متغیر SqlAdapter هست (adapter) خوب اگه دقت کنی ما استفاده از متد Fill به adapter ، متغیر dataset و همینطور نام جدول مورد نظر رو بهش پاس دادیم حالا داخل متغیر dataset چطور پر کردیم؟ ، با استفاده از دستور پایین

dataset.Tables["Students"].Rows.Add(row);

و درآخر هم (خط شماره 30 ) با استفاده از متد update دیتاست مون رو بروز کردیم در واقع همون جدول رو نسبت به اون عملیاتی که از خط 19 تا 26 انجام دادیم بروز میکنه
در کل منظورم این بود که همه این روند که عرض کردم به این زنجیر وار به هم متصل هستند . در خصوص سوال دوم : بله درواقع از SQLCommandBuilder هم استفاده کردیم تا عملیات روی بانکمون هم اعمال بشه

Mahmoud.Afrad
جمعه 26 شهریور 1395, 20:29 عصر
دوستان پاسخ دادند؛ فقط یک نکته بگم که اگر فقط نیاز به درج اطلاعات دارید و نیازی به دریافت اطلاعات از جدول نیست میتونید خط 17 رو به شکل زیر بنویسید
adapter.FillSchema(dataset, SchemaType.Mapped , "Students");

csharp.net
شنبه 27 شهریور 1395, 06:49 صبح
بسیار ممنون بابت راهنمایی شما سه بزرگوار، به عنوان اخرین سوال، دوستان بنده یه بار خودم کد رو توضیح بدم و هر جاش مشکل داره راهنمایی بفرمایید :

1- ارتباط با بانک را برقرار می کنیم
2- دستور Select ی رو می نویسیم و اونو به دیتا آداپتر می دیم تا یک DataTable تو DataSet ایجاد کنه
3- یک سطر به Datatable اضافه می کنیم
4- DataTbale رو به وسیله متد Update بروزرسانی می کنیم تا تغییرات مشخص بشه.


خب متد fill داده ها رو از بانک میاره واسه دیتا ست و متد update هم بعد از اینکه یک سطر اضافه شد تغییرات دیتاست رو به بانک منعکس می کنه، پس نقش این builder چیه؟

مشکل اصلی من با این کلاس اینه که چطور با وجودیکه فقط یک شیء از این کلاس ایجاد کردیم و هیچ جای دیگه ازش استفاده نکردیم دستور رو تولید می کنه ، در کل این شیء بلا استفاده کارش رو چطور انجام میده؟ دستور رو کجا قرار میده؟

این شیء adapter که به سازنده این کلاس ارسال شده حامل چیه؟ یعنی چی داخلشه که به کلاس builder پاس داده شده؟ کلاس builder از این شیء چه استفاده ای می کنه؟

یعنی همونطور که دوست عزیزمون ali_md110 (http://barnamenevis.org/member.php?18325-ali_md110) فرمودن یک event اینو به دیتاآداپتر اطلاع میده و سپس کلاس builder تغییرات رو به بانک اصلی منعکس میکنه؟