بسم الله الرحمن الرحيم
السلام عليكم جميعاً,,
عند عمل أي برنامج للإتصال بقاعدة بيانات في فيجوال ستوديو 2005, يتم بشكل افتراضي إضافة الـConnectionString إلى ملف الـApplication.Settings الخاص بالمشروع, وهذا عند بناء أي TableAdapter في أي Dataset, وربما تريد وقت التشغيل أو الـRun-Time تغيير هذه القيمة إلى مسار آخر لقاعدة البيانات, وحاولت مراراً تغيرها بالشكل التقليدي وهو:
My.ConnectionString="new connection path"
ولكن الطريقة فشلت! وذلك لإن أي ConnectionString يقوم الفيجوال بتخزينها يخزنها على هيئة Application Scope وليس User Scope وبالتالي فإنه لا يسمح بتغييرها وقت التشغيل! وستجد قبل هذا كله أن الجملة بالأعلى لن تعمل معك لإن My.ConnectionString هي للقراءة فقط أو Read-Only method....فما هو الحل ؟؟
هناك حل "غير احترافي" وهو أن نقوم بتغيير الـConnectionString لكل TableAdapter في الـDataset, ولكن في المشاريع الضخمة قد يكون هذا الحل مزعج أن نقوم بتغير عشرين أو خمس وعشرين وصلة اتصال أو ConnectionString ناهيك عن كونه يفتقد للمهارة والاحترافية المطلوبة في المبرمج....
فبدلاً من أن نغيير الأماكن التي ينصب فيها مجرى المياه نستطيع أن نغير مجرى المياه فقط ....ولكن كيف وقد ذكرنا أن ذلك ممنوع ؟
الحل هو : To Work around it...أو أن تلتف حول الموضوع لتجد حل بديل...وهذا أسلوب شائع لدى المبرمجين...
من المعروف أنه حتى الـApplication scoped items هي في الواقع يمكن تغييرها قبل الارتباط ...ولكن بطريقة ملتوية...
كيف ؟
لنفرض أنك أضفتك في برنامجك ConnectionString اسمها "MyConnectionString" ...
1- قم بإضافة مادة أو Item لنفس الـApplication settings باسم نفس الـConnectionString ولكن أضف لها جملة تعرفها على أنها قابلة للتعديل مثلاً: MyConnectionStringUserOverride
انتبه: MyConnectionStringUserOverride هي من نوع String أي أنها User scoped وليست Application scoped فانتبه لهذا جيداً ...
2- سنقوم بإضافة موديول صغير يقوم بإجراء بعض التعديلات على فئة My.Settings للسماح لها بقراءة التعديلات الجديدة وجعلها هي نفسها MyConnectionString
3- قم بإضافة موديول بهذا الكود:
Option Strict On
Option Explicit On
Namespace My
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared userOverrides() As String = {"acclogConnectionString"}
Private Shared userOverrideSuffix As String = "UserOverride"
Public Sub SetUserOverride(ByVal [property] As String, ByVal value As String)
Me([property]) = value
End Sub
Private Sub userOverride_SettingsLoaded(ByVal sender As Object, ByVal e As System.Configuration.SettingsLoadedEventArgs) _
Handles Me.SettingsLoaded
Dim userProperty As String
For Each appProperty As String In userOverrides
userProperty = appProperty & userOverrideSuffix
If CType(Me(userProperty), String).Length > 0 Then
Me(appProperty) = Me(userProperty)
End If
Next
End Sub
Private Sub userOverride_SettingsSaving(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) _
Handles Me.SettingsSaving
Dim userProperty As String
For Each appProperty As String In userOverrides
userProperty = appProperty & userOverrideSuffix
Me(userProperty) = Me(appProperty)
Next
End Sub
End Class
End Namespaceكيف يعمل هذا الكود ؟
قمنا بتعريف Array تحتوي اسم الـConnectionString التي لا نستطيع تغيرها في الـSettings
ثم قمنا بإضافة متغير اسمه userOverrideSuffix وهو يحوي جملة "User Override" وهي الجملة الإضافية التي قلنا أننا سنضيفها لاسم أي ConnectionString نريد تغيرها...
فقلنا لو أن اسم الـConnectionString هو MyConnectionString فبالإضافة تكون MyConnectionStringUserOverride
ثم نقوم بربطها بجملتنا المعدلة قبل أن يتم تحميل الـMy.Settings ثم نفرض التغيير عليها...
مثال:
في المثل أعلاه الـConnectionString أعلاه هي acclogConnectionString
لنفرض أنها تشير إلى هذه القاعدة:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\acclog.mdb
لنفترض الآن أننا نريد تغييرها من الكود وقت التشغيل...سنقوم بعمل التالي:
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
My.Settings.SetUserOverride("accLogConnectionString", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\acclog2.mdb")
End Subستلاحظ الآن أن الـConnectionString تغيرت من القاعدة C:\acclog.mdb إلى C:\acclog2.mdb
ملاحظة: المقالة مستوحاة من المقالة التالية:
http://www.codeproject.com/KB/vb/PersistCo...x?display=Print
بالتوفيق للجميع,,
لؤي الشريف