پرس و جو در دیتابیس Access

در این درس ما یک برنامه برای پرس و جو و اتصال به یک منبع داده‌ای اکسس می‌سازیم. ویژوال استودیو را باز می‌کنیم و یک برنامه ویندوزی ایجاد کرده و نام پروژه را AccessConnection می‌گذاریم. سه برچسب و سه Textbox بر روی آن قرار می‌دهیم و نام برچسب‌ها را به First Name ،Last Name و Age و خصوصیت اسم (name) مربوط به textbox ها را به txtFirstName ،txtLastName و txtAge تغییر می‌دهیم. چهار دکمه به این فرم اضافه می‌کنیم و اسم آن‌ها را به btnFirst ،btnNext ،btnLast و btnPrev تغییر می‌دهیم.
access-connection-01
بر روی این فرم دابل کلیک می‌کنیم تا کد زیر که مربوط به فرم است را برای ما بسازد.

using System;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;

namespace AccessConnection
{
    public partial class Form1 : Form
    {
        private OleDbConnection connection;
        private OleDbCommand command;
        private OleDbDataAdapter adapter;
        private DataSet dataset;
        private string firstname;
        private string lastname;
        private int age;
        private int position;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            connection = new OleDbConnection();
            command = new OleDbCommand();
            adapter = new OleDbDataAdapter();
            dataset = new DataSet();

            connection.ConnectionString =
                @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:Members.accdb;" +
                "Persist Security Info=False";

            command.Connection = connection;
            command.CommandText = "SELECT * FROM Members";

            adapter.SelectCommand = command;

            try
            {
                adapter.Fill(dataset, "Members");
            }
            catch (OleDbException)
            {
                MessageBox.Show("Error occured while connecting to database.");
                Application.Exit();
            }

            ShowValuesOfRow(0);
        }

        private void ShowValuesOfRow(int pos)
        {
            DataRow row = dataset.Tables["Members"].Rows[pos];
            position = pos;

            firstname = row["FirstName"].ToString();
            lastname = row["LastName"].ToString();
            age = (int)row["Age"];

            txtFirstName.Text = firstname;
            txtLastName.Text = lastname;
            txtAge.Text = age.ToString();
        }
    }
}

ما از System.Data.Oledb به عنوان فضای نام استفاده می‌کنیم. این فضای نام شامل کلاس‌هایی برای کار کردن با دیتابیس Access و همچنین کلاس DataSet، برای نگهداری اطلاعات و کار با آن‌ها می‌باشد. OleDbConnection را برای ایجاد ارتباط با دیتابیس و گرفتن اطلاعات، OleDbCommand را برای ساختن دستور مورد نظر، DataSet و یک سری فیلد برای نگهداری مقادیر دیتابیس درست می‌کنیم. فیلد position به ما می‌گوید که کدام سطر را باید در textbox نمایش دهیم. در داخل کنترل کننده رویداد مربوط به Load، اشیاء لازم برای وصل شدن به دیتابیس و سپس connectionString مربوط به OleDbConnection را مقداردهی می‌کنیم. این connection string اطلاعات لازم برای اتصال به دیتابیس را در اختیار ما قرار می‌دهد. همچنین دستور مربوط به Sql را در CommandText مشخص می‌کنیم. این دستور مشخص می‌کند که تمام اطلاعات و ردیفهای دیتابیس Members را بگیریم. در خط 38 خصوصیت مربوط به SelectCommand مربوط به OleDbDataAdapter را با command مقداردهی می‌کنیم. از متد ()OleDbDataAdapter.Fill برای اجرا کردن دستوری که در SelectCommand وجود دارد استفاده می‌کنیم تا اطلاعات را در DataSet مربوطه وارد کند، برای اینکه اگر استثنایی رخ داد بتوانیم آن را کنترل کنیم، این کد را در try … catch وارد کرده‌ایم. از متد ()ShowValuesOfRow استفاده می‌کنیم که مقادیر آن ردیف یا ایندکس را نمایش دهیم. عدد صفر را به عنوان آرگومان به این تابع می‌فرستیم تا این تابع ردیف اول را به نشان دهد. در داخل متد با استفاده از خصوصیت Tables در شیء DataSet و با استفاده از خصوصیت Rows که مربوط به Tables است ردیف مربوطه را در می‌آوریم و یک DataRow می‌سازیم و به آن منتسب می‌کنیم. ما می‌خواهیم از جدول Members این مورد را استخراج کنیم که با استفاده از خود اسم جدول این کار را می‌کنیم. هم چنین می‌خواهیم آن ردیف از جدول را برداریم که ایندکس آن pos است که همه این موارد را در خط 55 می‌بینیم. نتیجه در شیء DataRow که یک ردیف در DataTable را برای ما مشخص می‌کند را مشخص می‌کند سپس position را مقداردهی می‌کنیم. سپس مقدار هر ستون از DataRow به فیلد آن مقداردهی می‌شود و آن فیلد را به TextBox مربوطه منتصب می‌کنیم تا در فرم نمایش داده شود مانند شکل زیر.
access-connection-02
حالا برای دکمه‌ها باید تعریف کنیم که چه کاری باید انجام دهند. اول بر روی btnFirst کلیک می‌کنیم و تا کد خود را به آن اضافه کنیم. کد زیر را به آن اضافه می‌کنیم.

private void btnFirst_Click(object sender, EventArgs e) 
{
    ShowValuesOfRow(0);
}

کاملاً مشخص است که این کد برای ما چه کاری انجام می‌دهد. متد ()ShowValueOfRow را با آرگومان 0 صدا می زند که در واقع ردیف یک را به ما نمایش می‌دهد. برای btnLast بر روی آن کلیک می‌کنیم و مقدار زیر را به آن اضافه می‌کنیم.

private void btnLast_Click(object sender, EventArgs e)
{
    int lastIndex = dataset.Tables["Members"].Rows.Count - 1;

    ShowValuesOfRow(lastIndex);
}

با استفاده از خصوصیت Count از Row تعداد ردیفهایی که در جدول Members قرار دارد را بدست می‌آوریم و یک واحد از آن کم می‌کنیم که کار ایندکس را برای ما انجام دهد (ایندکس از 0 شروع می‌شود) و از این ایندکس (که ایندکس آخر است) استفاده می‌کنیم و آن را به تابع ShowValuesOfRow می‌دهیم تا ردیف آخر را برای ما در textbox ها نمایش دهد. در کد زیر هم کد مربوط به btnPrev را نمایش می‌دهیم.

private void btnPrev_Click(object sender, EventArgs e)
{
    if (position > 0)
    {
        position--;
        ShowValuesOfRow(position);
    }
}

در کد بالا یک واحد از position کم می‌کنیم و نمایش می‌دهیم. در داخل شرط If هم اول چک می‌کنیم که از صفر کمتر نشده باشد که اگر کمتر شود در داخل تابع ShowValuesOfRow به ما Exception می‌دهد (indexOutOfRang Exception). در کد زیر هم btnNext را نمایش می‌دهیم.

private void btnNext_Click(object sender, EventArgs e)
{
    int lastIndex = dataset.Tables["Members"].Rows.Count - 1;

    if (position < lastIndex)
    {
        position++;
        ShowValuesOfRow(position);
    }
}

در این کد هم مانند قبل ایندکس آخر را بدست می‌آوریم و از آن برای اینکه مقدار position از آن بیشتر نشود استفاده می‌کنیم (این کار را در شرط if انجام می‌دهیم). اگر این چک نشود ممکن است ما به جایی از جدول دسترسی پیدا کنیم که وجود ندارد (بیشتر از تعداد ردیفها جلو برویم) که در این صورت exception می‌دهیم (IndexOutOfRange Exception).
حالا برنامه را اجرا می‌کنیم و می‌توانیم با استفاده از دکمه First به ردیف اول و با دکمه Prev به ردیف قبلی و با دکمه Next به ردیف بعدی و با دکمه Last به ردیف آخر دسترسی پیدا کنیم.
ما می‌توانیم از همین کد برای وصل شدن به دیتابیس با Sql Data source استفاده کنیم تنها کاری که باید بکنیم این است که نوع provider را تغییر دهیم. و هیمچنین باید Connection string را تغییر دهیم که با Sql server سازگار باشد.

لطفا اگر نظر، پیشنهاد و یا انتقادی در باره مطلب بالا دارید در قسمت زیر و اگر سوالی دارید در بخش پرسش و پاسخ مطرح بفرمایید.

  1. Csharp پاسخ دادن

    سلام
    لطفا سورس رو هم قرار بدین

  2. Blue Lotus پاسخ دادن

    سلام ممنون از این آموزش عالی
    من یک مشکلی دارم
    هنگام اجرا با این خطا مواجه میشم The ‘Microsoft.ACE.OLEDB.12.0’ provider is not registered on the local machine.
    مشکل از کجاست ؟
    فقط من از اکسس ۲۰۱۳ استفاده میکنم تفاوتی وجود داره ؟

    • یونس ابراهیمی پاسخ دادن

      سلام …لطف دارین
      ممنون میشم سوالتونو توی انجمن مطرح بفرمایید.
      با تشکر

  3. azita.rahmani پاسخ دادن

    سلام.من هم مشکل آقا یا خانوم blue lotus رو دارم و خیلی عجله دارم واسه حل این مشکل

  4. seyedhosseinhosseinikhalili پاسخ دادن

    جناب ابراهیمی سوالم را دوباره طرح میکنم من هم مثل اقا یا خانم Blue Lotusهمون مشکل را دارم
    سورس بالا را در محیط ویژوال کپی و اجرا کردم در سطر
    try
    {
    adapter.Fill(dataset, “Members”);
    }
    پیغام زیر را میده
    The ‘Microsoft.ACE.OLEDB.12.0’ provider is not registered on the local machine.
    از اینکه دوباره سوالم را مطرح میکنم پوزش میخوام

    • یونس ابراهیمی پاسخ دادن

      تلگرامتون رو چک بفرمایید

  5. seyedhosseinhosseinikhalili پاسخ دادن

    به نظرمیاد پیغام
    The ‘Microsoft.ACE.OLEDB.12.0′ provider is not registered on the local machine.
    مبتلابه تعداد زیادی از کاربران باشه یه فکر اساسی کنیدجناب ابراهیمی

  6. seyedhosseinhosseinikhalili پاسخ دادن

    جناب ابراهیمی سلام
    علیرغم نصب ۲۰۱۵ همان پیغام بالا را میده قبلا یه راه حلی داشتین دو باره بفرمایید شاید جواب گرفتم
    البته من متن برنامه را همین پست گرفتم