انجام عملیات CRUD در LINQ و SQL

28 اردیبهشت 1398
درسنامه درس 12 از سری آموزش LINQ
LINQ-CRUD-SQL

با سلام خدمت کاربران عزیز با قسمت دوم آموزش LINQ to SQL در خدمت شما هستیم در این جلسه قصد داریم Delete و Insert و Update را بررسی کنیم.

در قسمت قبلی آموزش Select اطلاعات را پیاده سازی کردیم، حال اجازه دهید این بخش را با عملکرد Delete شروع کنیم.

 Delete اطلاعات

کد مربوط به قسمت Delete به صورت زیر است آن را به پروژه اضافه کنید و به توضیحات خط به خط آن دقت کنید:

 private void btnDelete_Click(object sender, EventArgs e)
        {
            int id = int.Parse(dataGridView1.CurrentRow.Cells["ID"].Value.ToString());
            ContactModelDataContext context = new ContactModelDataContext();
            var query = (from x in context.Contacts where x.ID == id select x).FirstOrDefault();
            context.Contacts.DeleteOnSubmit(query);
            context.SubmitChanges();
        }

خط یک برنامه مربوط به رویداد کلید btnDelete است. در SQL به یاد دارید که بهترین راه برای حذف یک رکورد موجود در جدول، استفاده از ID آن رکورد است. در اینجا نیز از ID استفاده می کنیم در واقع کلیات کار کاملا شبیه به SQL است فقط روش اجرای آن کمی متفاوت می باشد. ID را می توان از روش های مختلفی به دست آورد مثلا از یک TextBox ساده که ID توسط کاربرد وارد می شود اما یکی از بهترین روش ها برای گرفتن ID کلیک بر روی سطر و رکورد مورد نظر است که در خط سه این عمل را انجام داده ایم.

توجه داشته باشید نوع پارامتر گرفته شده در این روش از نوع string است که لازم است به int تبدیل شود. به [Cells["ID" دقت نمایید. این نام باید دقیقا مشابه فیلد تعریف شده در جدول اصلی باشد. در خط چهارم یک شی از کلاس ContactModelDataContext  تعریف کرده ایم. البته لازم نیست برای پیاده سازی هر قسمت دوباره این شئ را تعریف کنیم شما می توانید این شی را یک بار در بالای برنامه تعریف کنید و هر جا که لازم بود از آن استفاده کنید.

در خط پنجم با استفاده از id، رکوردی که قرار است از جدول حذف شود را انتخاب می کنیم این دستور تا حد زیادی شبیه به Query های SQL است.

به متد FirstOrDefault توجه کنید همان طور که قبلا بررسی کردیم این متد اولین عضو موجود در یک مجموعه را باز می گرداند. موس را بر روی شئ query نگه دارید می بینید که یک شئ از کلاس Contact است. حالا متد FirstOrDefault را پاک کنید و دوباره نوع شئ query را مشاهده کنید که از نوع <IQueryable<Contact است اما برای ما کاربردی ندارد.

البته می توانید به جای متد FirstOrDefault از SingleOrDefault هم استفاده کنید.

در خط ششم با استفاده از متد  DeleteOnSubmit رکورد گرفته شده در مرحله ی قبل را حذف می کنیم. دقت کنید که پارامتر ورودی این متد یک شئ از نوع کلاس Contact است به همین دلیل در خط قبلی <IQueryable<Contact برای ما کارایی نداشت. خب تا اینجا عملیات حذف از جدول به درستی انجام شد اما نه تنها در جدول اصلی بلکه در جدول مدل شده که در داخل کلاس قرار دارد، برای اعمال هر گونه تغییرات بر روی جدول اصلی لازم است از متد SubmitChanges که توسط شئ اصلی فراخوانی می شود استفاده کنید.

برنامه را اجرا کرده و اطلاعات جدول را Load کنید. یکی از سطر های جدول را انتخاب کرده و دکمه ی Delete را کلیک کنید و بار دیگر روی دکمه ی LoadData کلیک کنید تا تغییرات را مشاهده کنید.

نکته: می توانید کد مربوط به Select داده ها را در یک متد مثلا با نام RefreshData قرار دهید و در قسمت هایی که نیاز به Load شدن مجدد اطلاعات دارد استفاده کنید مثلا بعد از عملیات Delete.

در این صورت لازم نیست بعد از هر بار تغییر در جدول LoadData را کلیک کنید.

پیاده سازی متد کمکی RefreshData به صورت زیر است:

public void RefreshData()
        {
            IQueryable<Contact> allData = context.Contacts.Select(x => x);
            dataGridView1.DataSource = allData;
        }
private void btnDelete_Click(object sender, EventArgs e)
        {
            int id = int.Parse(dataGridView1.CurrentRow.Cells["ID"].Value.ToString());
            var query = (from x in context.Contacts
                        where x.ID == id
                        select x).SingleOrDefault();
            context.Contacts.DeleteOnSubmit(query);
            context.SubmitChanges();
            RefreshData();
        }

برای پیاده سازی کد Delete به روش Extension به شکل زیر عمل می کنیم:

var query = context.Contacts.Where(x => x.ID == id).FirstOrDefault();

 Insert اطلاعات

یکی از مباحث مهم در پایگاه داده بحث Insert کردن اطلاعات در جدول است. در این بخش به بررسی این عمل مهم می پردازیم.

کد مربوط به قسمت Insert به صورت زیر است آن را به پروژه اضافه کنید و به توضیحات خط به خط آن دقت کنید:

private void btnAdd_Click(object sender, EventArgs e)
        {
            string fname = txtName.Text;
            string lname = txtLastname.Text;
            string email = txtEmail.Text;
            string Number = txtNumber.Text;
            string address = txtAddress.Text;
            DateTime date = dateTimePicker1.Value;
            Contact obj = new Contact() { Name = fname, Lastname = lname, Email = email, MobileNumber = Number, Address = address, birthday = date};
            context.Contacts.InsertOnSubmit(obj);
            context.SubmitChanges();
            RefreshData();
        }

خط یکم برنامه مربوط به رویداد کلید btnAdd است.از خط سوم تا هشتم اطلاعاتی که قصد داریم در جدول ذخیره کنیم را از کاربر می گیریم. به کدی که  در خط هشت نوشته شده دقت کنید. نوع داده ای که از dateTimePicker1 گرفته می شود از نوع کلاس DateTime خواهد بود. هنگام ایجاد جدول هم فیلد birthday را از نوع Date انتخاب کردیم.

تذکر: به هیچ عنوان سعی نکنید به فیلد ID موجود در جدول مقدار دهی کنید چون موقع ایجاد جدول آن را از نوع Identity انتخاب کردیم تا به صورت خودکار و صعودی مقدار دهی شود. در صورت مقدار دادن به آن ممکن است با خطا مواجه شوید.

قبل از این که به توضیح خط نهم برنامه بپردازیم ابتدا به خط ده دقت کنید با استفاده از متد InsertOnSubmit می توانیم عمل Insert را پیاده سازی کنیم. دقت داشته باشید پارامتر ورودی این متد یک شئ از کلاس Contact است به همین دلیل در خط نهم آن شئ را با نام obj از کلاس Contact ایجاد و  فیلدهای آن را با اطلاعات گرفته شده از کاربر پر کرده ایم.

کافی است این شئ را به متد InsertOnSubmit ارسال نماییم تا عملیات Insert انجام شود. در خط یازدهم برای این که تغییرات بر روی جدول اصلی انجام شود از متد SubmitChanges استفاده شده است و در آخر با استفاده از متد کمکی RefreshData می توانیم تغییرات انجام شده را مشاهده کنیم.

برنامه را اجرا و اطلاعات را وارد کنید و با کلیک بر روی Add، رکورد مورد نظر را به جدول اضافه کنید.

نکته: برای این که بعد از اضافه کردن رکورد مورد نظر در جدول، TextBox ها خالی از اطلاعات قبلی شوند بهتر است متد زیر را پیاده سازی و در بخش Insert بعد از متد RefreshData فراخوانی کنید:

public void ClearText()
        {
            foreach (var item in this.Controls)
            {
                if(item.GetType() == txtAddress.GetType())
                {
                    TextBox box =(TextBox) item;
                    box.Clear();
                }
            }
        }

 Update اطلاعات

Update اطلاعات نسبت به سه عملیات قبلی شاید کمی پیچیده به نظر برسد. این قسمت از برنامه دارای دو بخش است

  1. گرفتن اطلاعات جاری و نمایش آن ها بر روی TextBox ها با کلیک بر روی رکوردی از جدول که قصد تغییر آن را داریم
  2. خواندن مجدد اطلاعات از TextBox و Update رکورد مورد نظر بر اساس ID

بخش اول: برای این که با کلیک بر روی هر ردیف از جدول اطلاعات آن سطر کاملا بر روی TextBox ها نمایش داده شود لازم است ابتدا کد زیر پیاده سازی شود:

        private void dataGridView1_Click(object sender, EventArgs e)
        {
            txtName.Text = dataGridView1.CurrentRow.Cells["Name"].Value.ToString();
            txtLastname.Text = dataGridView1.CurrentRow.Cells["Lastname"].Value.ToString();
            txtEmail.Text = dataGridView1.CurrentRow.Cells["Email"].Value.ToString();
            txtNumber.Text = dataGridView1.CurrentRow.Cells["Mobilenumber"].Value.ToString();
            txtAddress.Text = dataGridView1.CurrentRow.Cells["Address"].Value.ToString();
            DateTime date = (DateTime) dataGridView1.CurrentRow.Cells["birthday"].Value;
            dateTimePicker1.Value = date;
            int id = int.Parse(dataGridView1.CurrentRow.Cells["ID"].Value.ToString());
                                    
        }

توجه داشته باشید این کد باید در رویداد کلیک dataGridView1 نوشته شود. در خط های 3 تا 7 مقادیر گرفته شده از جدول به وسیله ی خاصیت text هر TextBox درون آن قرار می گیرد. در خط 8 نوع شئ تولید شده از نوع Object است پس لازم است به شئ DateTime تبدیل شود. این شئ حاوی تاریخ تولد رکورد مورد نظر است که از جدول استخراج شده و باید در خط 9 مورد استفاده قرار بگیرد.

قبل از انجام مرحله ی بعدی برنامه را اجرا کنید و بر روی یکی از سطر های جدول که حاوی اطلاعات است کلیک کنید، باید تمامی اطلاعات در جای مناسب بر روی فرم قرار بگیرند.

در خط 10 به متغییر id مقدار دهی شده که این مقدار برابر با ID رکوردی است که بر روی آن کلیک شده.

توجه به این نکته بسیار ضروری است که متغیر id برای این مورد باید به صورت سراسری تعریف شود چون در مرحله ی Update به آن نیاز داریم.

بخش دوم: در مرحله ی قبلی اطلاعات را از جدول استخراج کردیم تا با انجام تغییرات لازم آن ها را برای Update استفاده کنیم در این مرحله باید اطلاعات را دوباره از TextBox ها و dateTimePicker بخوانیم تا با کد مناسب آن ها را جایگزین رکورد قبلی کنیم. کد لازم برای اعمال Update به صورت زیر است:

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            string fname = txtName.Text;
            string lname = txtLastname.Text;
            string email = txtEmail.Text;
            string Number = txtNumber.Text;
            string address = txtAddress.Text;
            DateTime date = dateTimePicker1.Value;
            var obj = context.Contacts.Where(x => x.ID == id).FirstOrDefault();
            obj.Name = fname;
            obj.Lastname = lname;
            obj.MobileNumber = Number;
            obj.Address = address;
            obj.birthday = date;
            obj.Email = email;
            context.SubmitChanges();
            ClearText() 
        }

این کدها باید در رویداد کلیک btnUpdate نوشته شوند. خط های 3 تا 8 کاملا شبیه به قسمت Insert است و مقادیر گرفته شده از کاربر در متغیرهای مناسب ذخیره می شوند. به خط 9 دقت کنید به یاد دارید که در مرحله ی قبلی ID رکوردی که بر روی آن کلیک شده بود را در متغیر id که از نوع سراسری بود ذخیره کردیم تا شئ Contact مربوط به آن id را در اختیار بگیریم و تغییرات را روی آن انجام دهیم.

با استفاده از متد Where  اعلام کردیم که فقط رکوردی را انتخاب کن که دارای ID مشخصی است. به شئ obj دقت کنید که از نوع  کلاس Contact است بنابراین به وسیله ی آن به تمامی فیلدهای کلاس دسترسی داریم در خط های 10 تا 15 مقادیر جدید در شئ کلاس Contact قرار می گیرند و در خط بعدی توسط متد SubmitChanges تغییرات در جدول اصلی ذخیره می شوند. مشاهده می کنید که برای Update اطلاعات نیاز به استفاده از متد خاصی نیست. در پایان هم برای پاک کردن اطلاعات قبلی از روی TextBox ها از متد کمکی ClearText استفاده می کنیم.

سورس پروژه ای که در این دو بخش بررسی کردیم را می توانید از اینجا دانلود کنید. توجه کنید که حتما قبل از اجرای پروژه، جدول را در پایگاه داده ایجاد و آن را به پروژه متصل کنید.

اگر به هر دلیلی موفق به دانلود پروژه نشدید می توانید از کد کامل پروژه که به صورت زیر است استفاده کنید:

using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace LINQ_To_SQL_TEST
{
    public partial class Form1 : Form
    {
        ContactModelDataContext context = new ContactModelDataContext();
        public int id;

        public Form1()
        {
            InitializeComponent();
        }
       
        private void Form1_Load(object sender, EventArgs e)
        {
           
        }
        public void RefreshData()
        {
            IQueryable<Contact> allData = context.Contacts.Select(x => x);
            dataGridView1.DataSource = allData;
        }

        private void btnLoadData_Click(object sender, EventArgs e)
        {
            //---------------SELECT---------------------//
            RefreshData();
            ClearText();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            //------------DELETE-------------------
            int id = int.Parse(dataGridView1.CurrentRow.Cells["ID"].Value.ToString());
            var query = context.Contacts.Where(x => x.ID == id).FirstOrDefault();
            context.Contacts.DeleteOnSubmit(query);
            context.SubmitChanges();
            RefreshData();
            ClearText();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            //------------------INSERT----------------------
            string fname = txtName.Text;
            string lname = txtLastname.Text;
            string email = txtEmail.Text;
            string Number = txtNumber.Text;
            string address = txtAddress.Text;
            DateTime date = dateTimePicker1.Value;
            Contact obj = new Contact() { Name = fname, Lastname = lname, Email = email, MobileNumber = Number, Address = address, birthday = date};
            context.Contacts.InsertOnSubmit(obj);
            context.SubmitChanges();
            RefreshData();
            ClearText();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {      
            //--------------UPDATE------------------------------
            string fname = txtName.Text;
            string lname = txtLastname.Text;
            string email = txtEmail.Text;
            string Number = txtNumber.Text;
            string address = txtAddress.Text;
            DateTime date = dateTimePicker1.Value;
            var obj = context.Contacts.Where(x => x.ID == id).FirstOrDefault();
            obj.Name = fname;
            obj.Lastname = lname;
            obj.MobileNumber = Number;
            obj.Address = address;
            obj.birthday = date;
            obj.Email = email;
            context.SubmitChanges();
            ClearText();
        }

        private void dataGridView1_Click(object sender, EventArgs e)
        {
            txtName.Text = dataGridView1.CurrentRow.Cells["Name"].Value.ToString();
            txtLastname.Text = dataGridView1.CurrentRow.Cells["Lastname"].Value.ToString();
            txtEmail.Text = dataGridView1.CurrentRow.Cells["Email"].Value.ToString();
            txtNumber.Text = dataGridView1.CurrentRow.Cells["Mobilenumber"].Value.ToString();
            txtAddress.Text = dataGridView1.CurrentRow.Cells["Address"].Value.ToString();
            DateTime date = (DateTime) dataGridView1.CurrentRow.Cells["birthday"].Value;
            dateTimePicker1.Value = date;
            id = int.Parse(dataGridView1.CurrentRow.Cells["ID"].Value.ToString());

        }
        public void ClearText()
        {
            foreach (var item in this.Controls)
            {
                if (item.GetType() == txtAddress.GetType())
                {
                    TextBox box = (TextBox)item;
                    box.Clear();
                }
            }
        }

    }
}

حب دوستان این بخش از آموزش هم به پایان رسید در قسمت های بعدی آموزش مباحث پیشرفته تری از LINQ to SQL را بررسی خواهیم کرد.

موفق باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش LINQ توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علی
26 شهریور 1400
سپاس از نویسنده خیلی خوب بود

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سارا
13 بهمن 1399
خیلی خیلی ممنونم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.