• 0
bahaa1985

شرح:التعامل مع قاعدة البيانات بإستخدام LINQTOSQL

سؤال

السلام عليكم و رحمة الله و بركاته ..

في هذا الموضوع سوف أقوم بشرح كيفية عرض السجلات و تحديثها في قاعدة البيانات عن طريق المكون LINQTOSQL الموجود في الإصدار .NetFrameWork 3.5 فما أعلى، حيث أني وجدت ان هذه الطريقة أسهل نسبياً من التعامل مع DataSet و DataTable  و باقي عناصر ADO.Net ..

ما هو LINQTOSQL؟

هو مكون جديد من مكونات .NetFrameWork 3.5. و هو ضمن تكنولوجيا ORM (Oriental Relation Mapping) التي تختلف عن ODBC حيث أن الأخيرة هي خدمة تقوم أنت من خلالها بإنشاء إتصال مع قاعدة البيانات و جلب البيانات المطلوبة أو تعديلها أو حذفها بإستخدام مكونات تكنولوجيا ADO.Net التي تتيح لك التعامل مع قاعدة بياناتك من خلال أوامر SQL التي تكتبها في برنامجك بلغة .Net .

أما LINQToSQL فهي كما قلنا تقنية تخضع لORM، و هي خدمة تتيح لك عرض قاعدة البيانات كـcontext object و الجداول كـClasses و اذا كان هناك StoredProcedures في قاعدة بياناتك فيمكن عرضها كـMethods، و بعد ذلك تتعامل مع هذه Classes من خلال تقنية LINQ لإستخلاص البيانات التي تريدها.

إذاً LINQTOSQL تعني تحويل الجداول و الإجراءات المخزنة في قاعدة بياناتك لClasses و التعامل مع هذه Classes يكون من خلال LINQ عوضاً عن أوامر SQL، و هذا يعني أننا لن نستخدم تقنية ADO.NET.

و لكن مع ذلك فتقنية ADO.NET موجودة و لكن في الخفاء حيث أن تنفيذ الإستعلام او التعديل معناه الذهاب لقاعدة البيانات الحقيقية، و هذا يحتاج لـADO.NET  و لكن كما قلنا أنت لن تتعامل معها. و الصورة التالية توضح العلاقة بين LINQTOSQL و ADO.NET و قاعدة بيانات SQLSERVER :

[ملحوظة: هذه التقنية تعمل فقط مع قواعد بيانات MS SQLSERVER]


post-158674-0-57367500-1368560366.jpg

 

لتجربة هذه التقنية الرائعة سنقوم بعمل مشروع صغير. في هذا المشروع سنضيف عناصر قاعدة البيانات كـCLASSES ثم نربط COMBOBOX و DATAGRIDVIEW بهذه الCLASSES من خلال LINQ.

 

1- في البداية نقوم بإنشاء قاعدة بيانات SQLSERVER بإسم InterCompanyDB. ستكون قاعدة بياناتنا بهذه الشكل:

 

post-158674-0-21338300-1368560888_thumb.

 

2- نقوم بإنشاء مشروع Windows Forms جديد و نسميه LinqToSqlApplication.

3- نضيف المكون LINQTOSQL للمشروع عن طريق الضغط بالزر الأيمن للفارة على المشروع في الجزء Solution Explorer ثم إختيار Add ثم New Item، ثم من القسم Data نختار LINQ to SQL classes و سمّه InterClasses.

4- سيضيف فيجوال ستوديو الملف InterClases.dbml و بداخله ملفان فرعيان هما: InterClases.layout.dbml و InterClases.designer.cs، الملف الأول هو ملف model لـClasses (الجداول)، و الملف الثاني هو الكلاسات الفعلية بخصائصها و وظائفها.( لاحظ أن الأكواد لن تنشأ إلا بعد تنفيذ الخطوتين القادمتين).

5- سينشئ فيجوال ستوديو شاشة خالية بها قسمان خاليان. قم بإنشاء إتصال مع قاعدة البيانات التي أنشأتها، من خلال الجزء Server Explorer  بالطريقة المعتادة لتظهر لك الجداول و الإجراءات المخزنة.

6- قم بسحب و إلقاءها الجداول في المساحة الخالية و إذا كان هنا إجراءات مخزنة فقم بسحبها و إلقائها في الجزء الأيمن من الشاشة الخالية. كما في الصورة التالية:

 

post-158674-0-96596300-1368561809_thumb.

 

قم بفتح الملف InterClases.designer.cs، و إنظر إلى الكود داخله، ستجد الجداول قد مُثلت بـClasses :

 

post-158674-0-16243100-1368563155_thumb.

 

فلننظر لـClass InterClassesDataContext و نتفحص جزء من محتوياته:

 #region Extensibility Method Definitions    partial void OnCreated();    partial void InsertCompanies_Table(Companies_Table instance);    partial void UpdateCompanies_Table(Companies_Table instance);    partial void DeleteCompanies_Table(Companies_Table instance);    partial void InsertPorts_Table(Ports_Table instance);    partial void UpdatePorts_Table(Ports_Table instance);    partial void DeletePorts_Table(Ports_Table instance);    partial void InsertVoyages_Table(Voyages_Table instance);    partial void UpdateVoyages_Table(Voyages_Table instance);    partial void DeleteVoyages_Table(Voyages_Table instance);    partial void InsertVoyageType_Table(VoyageType_Table instance);    partial void UpdateVoyageType_Table(VoyageType_Table instance);    partial void DeleteVoyageType_Table(VoyageType_Table instance);    #endregion				public InterClassesDataContext() : 				base(global::LinqToSqlApplication.Properties.Settings.Default.InterCompany_DBConnectionString, mappingSource)		{			OnCreated();		}				public InterClassesDataContext(string connection) : 				base(connection, mappingSource)		{			OnCreated();		}				public InterClassesDataContext(System.Data.IDbConnection connection) : 				base(connection, mappingSource)		{			OnCreated();		}\\\المزيد من Constructors\\\\الخصائص:public System.Data.Linq.Table<Companies_Table> Companies_Tables		{			get			{				return this.GetTable<Companies_Table>();			}		}				public System.Data.Linq.Table<Ports_Table> Ports_Tables		{			get			{				return this.GetTable<Ports_Table>();			}		}				public System.Data.Linq.Table<Voyages_Table> Voyages_Tables		{			get			{				return this.GetTable<Voyages_Table>();			}		}				public System.Data.Linq.Table<VoyageType_Table> VoyageType_Tables		{			get			{				return this.GetTable<VoyageType_Table>();			}		}

هل رأيت الخصائص؟ إن قيمتها تساوي جدول.. مثلاً الخاصية  Voyages_Tables  هي من النوع العام System.Data.Linq.Table الذي يستقبل نوع محدد هو Voyages_Table

سوف أكمل في وقت لاحق إن شاء الله..في المرة القادمة سنقوم بإستخدام LINQ لإستخلاص البيانات  و ربط ComboBox و DataGridView بـClasses التي تمثل الجداول ثم إضافة سجلات جديدة أو تعديلها او حذفها.

 

تم تعديل بواسطه بهاء صلاح الدين
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

4 إجابة على هذا السؤال .

  • 0

اكرمك الله الي الامام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله و بركاته..

فلنلق نظرة على أحد الـClasses و ليكن مثلاً  Ports_Table:
 

public partial class Ports_Table : INotifyPropertyChanging, INotifyPropertyChanged    {                private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);                private int _ID;                private string _PortName;                private EntitySet<Voyages_Table> _Voyages_Tables;                private EntitySet<Voyages_Table> _Voyages_Tables1;            #region Extensibility Method Definitions    partial void OnLoaded();    partial void OnValidate(System.Data.Linq.ChangeAction action);    partial void OnCreated();    partial void OnIDChanging(int value);    partial void OnIDChanged();    partial void OnPortNameChanging(string value);    partial void OnPortNameChanged();    #endregion                public Ports_Table()        {            this._Voyages_Tables = new EntitySet<Voyages_Table>(new Action<Voyages_Table>(this.attach_Voyages_Tables), new Action<Voyages_Table>(this.detach_Voyages_Tables));            this._Voyages_Tables1 = new EntitySet<Voyages_Table>(new Action<Voyages_Table>(this.attach_Voyages_Tables1), new Action<Voyages_Table>(this.detach_Voyages_Tables1));            OnCreated();        }                [Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]        public int ID        {            get            {                return this._ID;            }            set            {                if ((this._ID != value))                {                    this.OnIDChanging(value);                    this.SendPropertyChanging();                    this._ID = value;                    this.SendPropertyChanged("ID");                    this.OnIDChanged();                }            }        }                [Column(Storage="_PortName", DbType="NVarChar(30)")]        public string PortName        {            get            {                return this._PortName;            }            set            {                if ((this._PortName != value))                {                    this.OnPortNameChanging(value);                    this.SendPropertyChanging();                    this._PortName = value;                    this.SendPropertyChanged("PortName");                    this.OnPortNameChanged();                }            }        }                [Association(Name="Ports_Table_Voyages_Table", Storage="_Voyages_Tables", ThisKey="ID", OtherKey="DepartPort_ID")]        public EntitySet<Voyages_Table> Voyages_Tables        {            get            {                return this._Voyages_Tables;            }            set            {                this._Voyages_Tables.Assign(value);            }        }                [Association(Name="Ports_Table_Voyages_Table1", Storage="_Voyages_Tables1", ThisKey="ID", OtherKey="ArrivalPort_ID")]        public EntitySet<Voyages_Table> Voyages_Tables1        {            get            {                return this._Voyages_Tables1;            }            set            {                this._Voyages_Tables1.Assign(value);            }        }                public event PropertyChangingEventHandler PropertyChanging;                public event PropertyChangedEventHandler PropertyChanged;                protected virtual void SendPropertyChanging()        {            if ((this.PropertyChanging != null))            {                this.PropertyChanging(this, emptyChangingEventArgs);            }        }                protected virtual void SendPropertyChanged(String propertyName)        {            if ((this.PropertyChanged != null))            {                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));            }        }                private void attach_Voyages_Tables(Voyages_Table entity)        {            this.SendPropertyChanging();            entity.Ports_Table = this;        }                private void detach_Voyages_Tables(Voyages_Table entity)        {            this.SendPropertyChanging();            entity.Ports_Table = null;        }                private void attach_Voyages_Tables1(Voyages_Table entity)        {            this.SendPropertyChanging();            entity.Ports_Table1 = this;        }                private void detach_Voyages_Tables1(Voyages_Table entity)        {            this.SendPropertyChanging();            entity.Ports_Table1 = null;        }    }


نلاحظ في هذا الكود الآتي:

1-  أن هذا الـClass يطبق الواجهتين INotifyPropertyChanging, INotifyPropertyChanged، و هاتان الواجهتان توفران طرقاً لتنبيه الأدوات المرتبطة بالخصائص الموجودة في الـClass بتغير قيمة هذه الخصائص، فمثلاً لو لديك اداة ListBox و قمت بتعيين الخاصية DisplayMember لPortName و حدث تغير في قيمة PortName فإن التغيير في قيمة DisplayMember سيحدث فوراً و ستشاهده أمامك.

2-الحقول ID,Portname تمث في الـClass كخصائص.

3-أيضاً العلاقات مع جدول   Voyages_table ممثلة كخصائص.

4- الأحداث public event PropertyChangingEventHandler PropertyChanging/public event PropertyChangedEventHandler PropertyChanged

مشتقة من الواجهتينINotifyPropertyChanging, INotifyPropertyChanged و هي تستغل من الوظيفتين ()SendPropertyChanged(),SendProperyChanging للتنبيه بتغير قيمة الخاصية.

و هذا أحد دلائل قوة LINQTOSQL .. فأنت هنا تستخدم الجداول كـClasses التي تطبق الواجهتين INotifyPropertyChanging, INotifyPropertyChanged لإكتشاف التغير في قيمة الحقل بدون كتابة المزيد من الكود من أجل فحص هذا الت

و الآن فلنقم بتجربة الكود عملياً .. لذا أضف للفورم DatagridView و 4 ComboBoxes و TextBox:

post-158674-0-49683700-1368717126_thumb.

1- في البداية ننشئ  Object من InterClassesDataContext Class حيث أنه الـClass الرئيسي الذي يمثل قاعدة البيانات و من خلاله نقوم بالإستعلام و الإضافة و التعديل و الحذف في السجلات.
 

InterClassesDataContext inter_dc = new InterClassesDataContext();


2- نقوم بملء Comboboxes في الحدث Form1_Load:
 

//fill the comboboxes:            combo_depart.DataSource = inter_dc.Ports_Tables;            combo_arrival.DataSource = inter_dc.Ports_Tables;            combo_company.DataSource = inter_dc.Companies_Tables;            combo_voyagetype.DataSource = inter_dc.VoyageType_Tables;

لو قمت بعمل run للمشروع و إخترت مثلاً مطار الكويت كمطار الإقلاع فستجد أن مطار الوصول قد تغير و أصبح مطار الكويت هو الآخر..السبب في ذلك أن كلا الـComboboxes مرتبطان بالخاصية PortName  و تلك الخاصية تقع في الـPorts_table Class التي تطبق الواجهتين INotifyPropertyChanging, INotifyPropertyChanged، و لا داعي لتكرار شرحهما حتى لا أكون مملاً.. و لكن أعتقد انك فهمت فائدة هاتين الواجهتين و كيفية إستغلال الحدثين PropertyChanging/PropertyChanged لتنبيه الأدوات بتغير قيمة الخاصية المرتبطة بهم.

طبعاً نحن لا نريد أن يكون الـComboboxes مرتبطان مع بعضهما البعض..لذا سنضطر للذهاب للملف InterClases.layout.dbml و إدراج الجدول Ports_Table مرة أخرى .. لأن هذا الجدول موجود من قبل فسيتم تسمية الجدول الجديد Ports_Table2 و سنلاحظ إضافة الخاصية Ports_Table2s لـInterClassesDataContext..

لذا سنقوم بملء  combo_arrival بهذا الكود:

  combo_arrival.DataSource = inter_dc.Ports_Table2s ;

عند إختيار مطار الإقلاع فلن يكون هو نفسه مطار الوصول.. الآن سنقوم بكتابة كود LINQ في الحدث Form1_Load() للإستعلام عن الرحلات و عرض النتيجة في الداتاجريد:

//Fill datagridview with voyages:            var vlist =                from v in inter_dc.Voyages_Tables                join vtp in inter_dc.VoyageType_Tables on v.VoyageType_ID equals vtp.ID                join c in inter_dc.Companies_Tables on v.Company_ID equals c.ID                join p1 in inter_dc.Ports_Tables on v.DepartPort_ID equals p1.ID                join p2 in inter_dc.Ports_Tables on v.ArrivalPort_ID equals p2.ID                select new                {                    ID = v.ID,                    VoNo = v.VoyageNo,                    Date = v.VoyageDateTime,                    DepartPort = p1.PortName,                    ArrivalPort = p2.PortName,                    VoCompany = c.CompanyName                };            dataGridView1.DataSource = vlist;

لمن يريد معرفة المزيد عن تقنية LINQ فيمكنه الإطلاع على هذا الموضوع :http://arabteam2000-forum.com/index.php/topic/245463-linq-to-everything/ و لكن الكود في هذا الموضوع بالفيجوال بيسك,, من يرغي في السي شارب فليبحث في جوجل و سيجد ضالته.

ستكون نتيجة الإستعلام بLINQ هكذا:

post-158674-0-33217700-1368724215_thumb.

 

كما تلاحظون ان عناوين الأعمدة هي نفسها أسماء خصائص Anonymous Type Vlist إذا أردنا جعل عناوين الأعمدة بالعربية نضيف أعمدة للداتا جريد و نعين الخاصية DataPropertyName للخاصية المناسبة لها في Vlist:

post-158674-0-09983400-1368730613_thumb.

 

نكمل لاحقا إن شاء الله .. في المرة القادمة سنتعلم ملء الداتا جريد مع الإستفادة من الواجهتين  INotifyPropertyChanging, INotifyPropertyChanged و حفظ و تعديل و حذف السجلات..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله و بركاته ...

المرة السابقة إستخدمنا هذا الكود لملء الداتا جريد:
 

//Fill datagridview with voyages:            var vlist =                from v in inter_dc.Voyages_Tables                join vtp in inter_dc.VoyageType_Tables on v.VoyageType_ID equals vtp.ID                join c in inter_dc.Companies_Tables on v.Company_ID equals c.ID                join p1 in inter_dc.Ports_Tables on v.DepartPort_ID equals p1.ID                join p2 in inter_dc.Ports_Tables on v.ArrivalPort_ID equals p2.ID                select new                {                    ID = v.ID,                    VoNo = v.VoyageNo,                    Date = v.VoyageDateTime,                    DepartPort = p1.PortName,                    ArrivalPort = p2.PortName,                    VoCompany = c.CompanyName                };            dataGridView1.DataSource = vlist;


هنا ستواجهنا مشكلة حيث أن الخصائص {ID,VoNo,Date,DepartPort,ArrivalPort,VoCompany} من النوع المجهول Anonymous Type  و هذا النوع من الخصائص للقراءة فقط..لذا عند ربط الداتاجريد بهذه الخصائص فإننا لن يمكننا تعديل أي شئ في الداتاجريد.

“Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to first explicitly define a type.”

لذا لمواجهة هذه المشكلة سنقوم بالآتي...سنقوم بعمل Class جديدة و نسميها VoyagesDetails و تطبق الواجهة INotifyPropertyChanged، ثم ننشئ الخصائص التي سنربطها بالداتاجريد .... أي سنجعل هذا الClass مشابه تماماً لClasses الموجودة في الملف InterClasses.designer.cs:
 

class VoyagesDetails:INotifyPropertyChanged    {        private int _ID;        public int ID        {            get { return _ID; }            set            {                _ID = value;                OnPropertyChanged("ID");            }        }        private string _VoNo;        public string VoNo        {            get { return _VoNo; }            set            {                _VoNo = value;                OnPropertyChanged("VoNo");            }        }        private DateTime _Date;        public DateTime Date        {            get { return _Date; }            set            {                _Date = value;                OnPropertyChanged("Date");            }        } private int _DepartPortID;        public int DepartPortID        {            get{return _DepartPortID ;}            set            {                _DepartPortID =value ;                OnPropertyChanged ("DepartPortID");            }        }         private int _ArrivalPortID;        public int ArrivalPortID        {            get { return _ArrivalPortID; }            set            {                _ArrivalPortID = value;                OnPropertyChanged("ArrivalPortID");            }        }         private int _CompanyID;        public int CompanyID        {            get { return _CompanyID; }            set            {                _CompanyID = value;                OnPropertyChanged("CompanyID");            }        }                public event PropertyChangedEventHandler PropertyChanged;        private void OnPropertyChanged(string propertyName)        {            if (PropertyChanged != null)            {                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));            }        }       static InterClassesDataContext inter_dc = new InterClassesDataContext();       public List<VoyagesDetails> DatagridVoyagesFill()        {            List<VoyagesDetails> voy_list = new List<VoyagesDetails>();            var vlist =                from v in inter_dc.Voyages_Tables                join vt in inter_dc.VoyageType_Tables on v.VoyageType_ID equals vt.ID                join c in inter_dc.Companies_Tables on v.Company_ID equals c.ID                join p1 in inter_dc.Ports_Tables on v.DepartPort_ID equals p1.ID                join p2 in inter_dc.Ports_Tables on v.ArrivalPort_ID equals p2.ID                select new                {                     ID = v.ID, VoNo = v.VoyageNo, Date = v.VoyageDateTime, DepartPortID=v.DepartPort_ID,DepartPort=p1.PortName,ArrivalPortID=v.ArrivalPort_ID ,ArrivalPort = p2.PortName , VoCompany =c.CompanyName,CompanyID=v.Company_ID                };            for (int i = 0; i < vlist.Count(); i++)            {                voy_list.Add                    (new VoyagesDetails                        {                            ID = vlist.First().ID,                            VoNo = vlist.First ().VoNo,                            Date = (DateTime)vlist.First().Date,                            DepartPortID =(int)vlist .First().DepartPortID ,                                                        ArrivalPortID =(int)vlist .First().ArrivalPortID ,                                                        CompanyID=(int)vlist .First ().CompanyID                        }                    );            }            return voy_list;        }    }

سيكون كود الربط هكذا:
 

//Fill datagridview with Voyages:VoyagesDetails vd = new VoyagesDetails();            dataGridView1.DataSource = vd.DatagridVoyagesFill();

فلنجعل الداتاجريد تبدو أكثر إحترافاً، لذا نغير نوع الاعمدة التي ستعرض الشركة و مطاري الإقلاع و الهبوط إلى النوع DataGridViewComboBox، و يجب أن تكون الخاصية DataPropertyName في عمود الشركة CompanyID و عمود الإقلاع DepartPortID و عمود الوصول ArrivalPortID (لاحظ أن هذه خصائص VoyagesDetails)،و نضيف عمودين من النوع DataGridViewButton كأزرار للتعديل و الحذف، ثم نكتب هذا الكود لملئهم في الحدث Form1_Load():

 

//fill departport column IQueryable  depart = from i in inter_dc.Ports_Tables select new { ID = i.ID, PortName = i.PortName };                        DepartColumn.DataSource = depart;            DepartColumn.DisplayMember = "PortName"; DepartColumn.ValueMember = "ID";            //// fill arrivalport column                                   IQueryable arrival = from i in inter_dc.Ports_Table2s select new { ID = i.ID, PortName = i.PortName };            ArrivalColumn.DataSource = arrival;            ArrivalColumn.DisplayMember = "PortName"; ArrivalColumn.ValueMember = "ID";              /// fill companies column               IQueryable company = from c in inter_dc.Companies_Tables select new { ID = c.ID, CompanyName = c.CompanyName };            CompanyColumn.DataSource = company;                      CompanyColumn.DisplayMember = "CompanyName"; CompanyColumn.ValueMember = "ID";


سيكون شكل الداتاجريد هكذا:

post-158674-0-05504300-1368920223_thumb.

و الآن فلننظر إلى كود حفظ  الرحلة في جدول Voyages_Table في قاعدة البيانات أسفل زر الحفظ :
 

Voyages_Table vt = new Voyages_Table                {                    VoyageNo = textBox1.Text,                    VoyageType_ID = (int)combo_voyagetype.SelectedValue,                    Company_ID = (int)combo_company.SelectedValue,                    VoyageDateTime = dateTimePicker1.Value,                    DepartPort_ID = (int)combo_depart.SelectedValue,                    ArrivalPort_ID = (int)combo_arrival.SelectedValue                 };                //save the list items to Voyage_Table in the real database:                inter_dc.Voyages_Tables.InsertOnSubmit(vt);                inter_dc.SubmitChanges();                MessageBox.Show("تم الحفظ بنجاح!", "", MessageBoxButtons.OK);

قمنا بإنشاء الكائن vt من Voyages_Table، ثم أعطينا كل خاصية في الكائن vt القيمة المناسبة لها من الأدوات، و للحفظ في قاعدة البيانات إستخدمنا الوظيفة InsertOnSubmit()  الموجودة في الخاصية  Voyages_Tables مع تمرير المعامل vt لها، ثم لتفعيل التغيير في قاعدة البيانات إستخدمنا inter_dc.SubmitChanges();.

 

و الآن حان دور التعديل و الحذف .. سنضع  أكوادنا أسفل الحدث dataGridView1_CellContentClick لأننا سنتعامل مع زري التعديل و الحذف في الداتاجريد:

 

if (e.ColumnIndex == but_update.Index)            {                                                      VoyagesDetails vd = (VoyagesDetails)dataGridView1.Rows[e.RowIndex].DataBoundItem;                Voyages_Table vt_row = inter_dc.Voyages_Tables.ToList().ElementAt(e.RowIndex);                vt_row.ArrivalPort_ID = vd.ArrivalPortID;                vt_row.DepartPort_ID = vd.DepartPortID;                vt_row.Company_ID = vd.CompanyID;                inter_dc.SubmitChanges();                MessageBox.Show("تم التعديل بنجاح!", "", MessageBoxButtons.OK);            }            else if (e.ColumnIndex == but_delete.Index)            {                VoyagesDetails vd = (VoyagesDetails)dataGridView1.Rows[e.RowIndex].DataBoundItem;                Voyages_Table vt = (from v in inter_dc.Voyages_Tables where v.ID == vd.ID select v).First ();                                inter_dc.Voyages_Tables.DeleteOnSubmit(vt);                inter_dc.SubmitChanges();                MessageBox.Show("تم الحذف بنجاح!", "", MessageBoxButtons.OK);            }

هنا سيتضح عرض الواجهة INotifyPropertyChanged التي جعلنا VoyagesDetails تطبقها..في البداية أنشانا متغيراً من النوع VoyagesDetails و هذا المتغير قيمته تساوي عناصر الصف الذي إخترته في الداتاجريد.. لماذا قمنا بهذه الخطوة؟ لأننا ربطنا الداتاجريد بـVoyagesDetails Class، ثم أنشانا المتغير vt_row من النوعVoyages_Table و قيمته تساوي صف محدد على أساس قيمة ID من جدول Voyages_Table.

إذا إخترت مثلاً شركة الإتحاد بدلاً من مصر للطيران و مطار الوصول أبو ظبي بدلاً من مطار الدوحة فإن قيم خاصيتي CompanyID و DepartPortID الموجودتان في الـVoyagesDetails ستتغيران..هذا هو سبب إستخدامنا للواجهة INotifyPropertyChanged..أنها تقوم بإشعارك بالتغير في قيمة الخصائص، لذا قمنا بجعل قيم الخصائص المطلوب تعديلها في Voyages_Table تساوي الخصائص المعدلة في  VoyagesDetails(قم بوضع breakpoint و راقب تغير قيمة خصائص vd ) ، و لتطبيق التعديلات على الجدول في قاعدة البيانات نستخدم الوظيفة inter_dc.SubmitChanges().

في كود الحذف قمنا بإختيار الصف المطلوب حذفه من جدول Voyages_Tables، ثم تطبيق الحذف بإستخدام الوظيفة  inter_dc.SubmitChanges();

---------------------------------------

الخلاصة:

1- LINQTOSQL هي لإستخدام تقنية LINQ للإستعلام من فئات في برنامجك..هذه الفئات تمثل الجداول في قاعدة بياناتك و تمثل الحقول كخصائص.

2-الفئة الرئيسية لديك هي الفئة الممثلة لقاعدة البيانات نفسها، حيث تقع فيها الخصائص التي قيمتها تساوي الجداول و الوظائف اللازمة للإضافة و التعديل و الحذف.

3- عند إستخدام فئة تطبق الواجهة INotifyPropertyChanged فإن أي تغير في قيمة خصائص هذه الفئة يظهر في الأدوات المرتبطة بهذه الخاصية.

4- ناتج إستعلام LINQ هو من النوع المجهول Anonymous Type.

5- إذا كنت تريد ربط الداتاجريد بإستعلام ناتج من عمل join لجدولين فالأفضل عمل Class خاص يحتوي على الحقول التي تريد عرضها على شكل خصائص مع تطبيق الواجهة INotifyPropertyChanged ثم ربط الداتاجريد بالـClass.

أتمنى أن أكون قد وفقت في شرح تقنية LINQTOSQL، و أعتذر مسبقاً إذا كان هناك صعوبة في فهم بعض النقاط..

السلام عليكم و رحمة الله و بركاته..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

تطبيق بسيط بLINQTOSQL لمن يريد..قم فقط بتعديل جملة الإتصال في ملف config لتتوافق معك.LinqToSqlApplication.rar

 

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .