سؤال

لدي تطبيق ويب يحتوي على ما يلي:

  • مشروع ويب (مع ملف web.config يحتوي على سلسلة اتصال - ولكن لا يوجد رمز وصول إلى البيانات في مشروع الويب)
  • مشروع وصول إلى البيانات يستخدم فئات LINQ-SQL لتوفير كيانات لواجهة مستخدم مشروع الويب (يحتوي هذا المشروع على ملف إعدادات وapp.config - وكلاهما يحتوي على سلاسل اتصال)

عندما أقوم بالإنشاء والنشر، لا يوجد ملف إعدادات أو app.config في دليل Bin مع الوصول إلى البيانات .dll، ولكن تغيير سلسلة الاتصال في ملف web.config لا يغير قاعدة البيانات وفقًا لذلك - لذا يجب أن تكون سلسلة الاتصال يتم تجميعها في الوصول إلى البيانات دلل.

ما أحتاج إليه هو ملف تكوين واحد للنشر بالكامل - موقع الويب، وملفات dll للوصول إلى البيانات، وكل شيء - يحتوي على سلسلة اتصال واحدة يتم استخدامها.في الوقت الحالي، يبدو أن هناك سلاسل اتصال متعددة يتم استخدامها أو تشفيرها في كل مكان.

كيف يمكنني حل هذه الفوضى بشكل أفضل؟

شكرا على اي مساعدة.

هل كانت مفيدة؟

المحلول

لم أواجه مشكلة مع طبقة الوصول إلى البيانات (DAL) القدرة على استخدام سلاسل الاتصال من my web.config ملف.عادةً ما أقوم بنسخ قسم سلاسل الاتصال من DAL ولصقه في ملف web.config.أنا أستخدم مصمم DBML لإنشاء سياق البيانات.

إذا لم ينجح هذا بالنسبة لك، فيمكنك تحديد سلسلة الاتصال في مُنشئ سياق البيانات.في مشروع الويب الخاص بك، يوجد فئة ثابتة تقوم بتحميل إعداداتك، بما في ذلك سلاسل الاتصال الخاصة بك، وعندما تقوم بإنشاء كائن DAL الخاص بك (أو سياق البيانات، إذا قمت بإنشائه مباشرة) فقط قم بتمريره إلى المُنشئ.

public static class GlobalSettings
{
    private static string dalConnectionString;
    public static string DALConnectionString
    {
       get
       {
           if (dalConnectionString == null)
           {
              dalConnectionString = WebConfigurationManager
                                      .ConnectionStrings["DALConnectionString"]
                                        .ConnectionString;
           }
           return dalConnectionString;
       }
    }
}
...

using (var context = new DALDataContext(GlobalSettings.DALConnectionString))
{
   ...
}

نصائح أخرى

سيحدد ملف التكوين الخاص بمشروع بدء التشغيل إعدادات التكوين لجميع المشاريع المضمنة.على سبيل المثال، إذا كان مشروع الويب الخاص بك هو مشروع بدء التشغيل، فإن أي مرجع إلى "appSettings" سيبحث عن الإعدادات من web.config، وهذا يتضمن أي إشارات إلى "appSettings" من مشروع الوصول إلى البيانات الخاص بك.لذا انسخ أي إعدادات تكوين من app.config لمشروع الوصول إلى البيانات إلى web.config الخاص بمشروع الويب.

قم بإنشاء ConnectionFactory الخاص بك استنادًا إلى السجل:

  • أضف مفتاح تسجيل لتطبيقك ضمن SOFTWARE/[YOUR_COMPANY]/[YOUR_APP]
  • أضف قيمة سلسلة لـ ConnectionString
  • قم بتعليم ConnectionFactory الخاص بك كيفية فتح مفتاح التسجيل المناسب (في مُنشئ ثابت، وليس كل تحميل للصفحة!).
  • قم بتصدير معلومات التسجيل كملف .reg، وأضفها إلى التحكم بالمصادر، وقم بتعديلها وتطبيقها حسب الضرورة لإعداد أجهزة إضافية.

طليعة:

  • بسيطة لاقامة
  • تعيش سلسلة الاتصال في مكان واحد
  • ليس موجودًا في web/app.config، لذا لا حاجة إلى ترميز الإعدادات الخاصة بالبيئة.
  • ليس موجودًا في web/app.config، لذلك لا يستطيع Junior Dev Jimmy أن يطلب من خادم الإنتاج الخاص بك عن طريق الخطأ أن ينظر إلى قاعدة بيانات DEV

يخدع:

  • ليس من الواضح على الفور أن هناك أشياء مهمة تعيش في السجل، لذلك سيحتاج المطورون الجدد إلى تعليمات.
  • خطوة إضافية عند تكوين جهاز نشر جديد
  • التسجيل هو oldskool.سوف يسخر منك المطورون الصغار.

شكرا على الردود.

أولئك منكم الذين يقولون إن التطبيق سيستخدم الإعداد الموجود في web.config على حق في الحالات التي أشير إليها في الكود الخاص بي:

_connectionString = ConfigurationManager.AppSettings["ConnectionString"];

.. ولكن هناك مشكلة مختلفة مع سياقات بيانات LINQ-SQL - أعتقد أنها تتضمن سلاسل اتصالات في ملف dll المترجم لاستخدامها في المُنشئ بدون معلمات.كما يقول tvanofosson، أحتاج إلى إنشاء سياقات بيانات عن طريق تمرير إشارة إلى سلسلة الاتصال في ملف web.config.حيث كنت أقع في التشابك :)

كان لدي القليل من الصراع مع هذه المشكلة أيضًا.لقد وجدت حلاً باستخدام تعريف فئة c# الجزئي وتوسيع سياق البيانات الذي أنشأه مصمم dbml.هذا الحل مشابه تمامًا لإجابة tvanfosson.ما عليك فعله هو إنشاء فئة datacontext جزئية مع المُنشئ الافتراضي الذي يحصل على ConnectionString من الإعدادات وفي خصائص DC لمصمم dbml قم بتعيين الاتصال على لا شيء.بهذه الطريقة لن يتم تجميع سلسلة الاتصال في ملف dll.سيحصل Datacontext تلقائيًا على سلسلة الاتصال من إعدادات سلسلة الاتصال web.config.لم أختبر ما إذا كان هذا يعمل مع app.config أيضًا، ولكن أعتقد أنه يجب أن يعمل بشكل جيد.

فيما يلي عينة من فئة DC الجزئية:

namespace MyApplication {
    /// <summary>
    /// Summary description for MyDataContext
    /// </summary>
    /// 
    public partial class MyDataContext
    {
        public MyDataContext() :
            base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
        {
            OnCreated();
        }
    }
}

سيستخدم تطبيقك فقط إدخالات التكوين في ملف web.config.يمكنك وضع إعداد dll في ملف web.config طالما أنها مبنية بشكل صحيح.المثال الخاص بي خاص بـ VB باستخدام My Namespace، لكنه يمنحك فكرة عامة.

في paret configSections لملف التكوين، ستحتاج إلى إدخال:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="YourAssembly.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup></configSections>

ثم في جزء إعدادات التطبيق من ملف التكوين، تضع الإدخالات لكل ملف dll:

    <applicationSettings>
      <YourAssembly.My.MySettings>
        <setting name="DebugMode" serializeAs="String">
            <value>False</value>
        </setting>
      </YourAssembly.My.MySettings>
    </applicationSettings>  

لإبقائه آمنًا من أي شيء في التعليمات البرمجية التي تم إنشاؤها تلقائيًا، قم بتجاوز معلومات الاتصال في طريقة OnCreated() لسياق البيانات:

using System.Configuration;
namespace MyApplication 
{
    partial void OnCreated()
    {
        // attempt to use named connection string from the calling config file
        var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
        if (conn != null) Connection.ConnectionString = conn.ConnectionString;
    }
}

بهذه الطريقة يمكن لمصمم dbml القيام بأشياء الاتصال بطريقته الخاصة (وهو أمر ليس جيدًا خارج مشروع الويب)، لكنك تحصل على التحكم النهائي في الاتصال عند تشغيل التطبيق.

إليك طريقة واحدة للنظر إليها.ما هو المكون الذي يجب أن يتخذ القرار بشأن قاعدة البيانات التي سيتم استخدامها؟من الممكن أن تتغير قاعدة البيانات (أو على الأقل سلسلة الاتصال) في المستقبل.هل يقرر موقع الويب قاعدة البيانات التي سيتم استخدامها؟أم أن DAL هو الذي يقرر؟

إذا كان لديك قواعد بيانات dev وQA وUAT وprod، فإن إدارة سلاسل الاتصال هذه أمر بالغ الأهمية.

إذا قرر موقع الويب ذلك، فيجب عليه تمرير سلسلة الاتصال من web.config الخاص به إلى DAL.إذا لم يكن من المفترض أن يعرف موقع الويب أو يهتم بمصدر البيانات، فإن سلسلة الاتصال تنتمي إلى DAL.

ماذا عن تعريف كائن ConnectionFactory، الذي يأخذ التعداد كمعلمة ويعيد كائن اتصال كامل التكوين؟

يمكنك أيضًا جعل تطبيق الويب يوفر سلسلة الاتصال عندما يحتاج إلى استخدام مشروع الوصول إلى البيانات.يمكنك جعله جزءًا من المنشئ.

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

في عالم مثالي، أعتقد أنك ستعيد بناء طبقة البيانات الخاصة بك لالتقاط إعدادات التكوين عبر System.Configuration أو المنشئات/المصانع ذات الصلة.بمعنى أنك تحتاج إما إلى إعادة توصيل مصدر التكوين الضمني الخاص به، أو تعيين الاتصالات بشكل صريح من المضيف/المستهلك.هناك نمط آخر ذو صلة لمركزية هذه الأنواع من الثوابت وهو رمي خاصية للقراءة فقط في فئة مساعدة ثابتة وجعل هذه الفئة تدير الدقة الفعلية من التكوينات، وما إلى ذلك.

أحد الأماكن التي يمكنك أن تنظر إليها والتي أعتقد أنها تعرض أمثلة جيدة لكيفية القيام بذلك بأناقة هو NHibernate وإدارة التكوين/التعيينات الخاصة به.من المؤكد أنه يشبه إلى حد ما جحيم XML، كما أن Fluent NHib أكثر سكرية، ولكن معظم عينات العالم الحقيقي ستوضح لك كيفية التوفيق بين التكوين من مجموعة داعمة مقابل مجموعة داعمة.الجمعية التنفيذية .

قم بإنشاء ConnectionFactory الخاص بك استنادًا إلى ملفات .config:

  • حدد قسم تكوين مخصص لتعيين أزواج المفاتيح/سلسلة الاتصال
  • قم بتعليم ConnectionFactory الخاص بك كيفية التعرف على قسم التكوين هذا باستخدام اسم المضيف أو اسم الجهاز حسب الاقتضاء
  • قم بتعبئة قيم المفتاح/سلسلة الاتصال لخوادم dev/qa/prod المختلفة، وقم بإفلاتها في تطبيقاتك المتنوعة مثل app.config وweb.config وما إلى ذلك.ملفات.

طليعة:

  • جميعهم يعيشون داخل المشروع، لذلك لا توجد مفاجآت
  • تعد إضافة هدف نشر إضافي بمثابة عملية نسخ/لصق في ملف ‎.config

يخدع:

  • يصنع أقسام XML كبيرة وقبيحة، خاصة إذا كان لديك عشرات من خوادم الإنتاج
  • يجب أن تتكرر بين المشاريع
  • يحتاج إلى تغيير الكود وإعادة النشر لإضافة هدف جديد
  • يحتاج الكود إلى معرفة البيئة التي سيعيش فيها

أعلم أن هذا أمر قديم ولكن إليك كيفية القيام بذلك (تعجبني طريقة @Seba تمامًا ولكني لم أحاول ذلك)

يفترض هذا أن ملف DBML الخاص بك موجود في مكتبة الفصل الخاصة به، والتي وجدتها أكثر ملاءمة عند مشاركة الكيانات والوصول إلى البيانات عبر مواقع ويب متعددة ومكتبات الفئات الأخرى.ويفترض أيضًا أنك قمت بتسمية سلسلة الاتصال الخاصة بك بنفس الطريقة في كل مشروع.أستخدم NAnt لتعيين هذا عندما أقوم بالنشر في بيئات مختلفة.

لقد استندت في هذا إلى الإجابة العليا أعلاه منtvanfosson - مجد لهذا الرجل.

  1. قم بإنشاء الفئة الأساسية الخاصة بك، والتي تشتق من LinqDataContext

إليك كود VB:

    Imports System.Configuration

Public Class CustomDataContextBase
    Inherits System.Data.Linq.DataContext
    Implements IDisposable

    Private Shared overrideConnectionString As String

    Public Shared ReadOnly Property CustomConnectionString As String
        Get
            If String.IsNullOrEmpty(overrideConnectionString) Then
                overrideConnectionString = ConfigurationManager.ConnectionStrings("MyAppConnectionString").ConnectionString
            End If

            Return overrideConnectionString
        End Get
    End Property

    Public Sub New()
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String)
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

    Public Sub New(ByVal connection As IDbConnection, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

End Class
  1. افتح ملف DBML الخاص بك، وفي الخصائص، أضف اسم الفئة أعلاه إلى خاصية الفئة الأساسية.

ملاحظة، إذا قمت بوضع فئة سياق البيانات المخصصة في نفس التجميع، فما عليك سوى تضمين اسم الفئة، على سبيل المثال.CustomDataContext.

إذا كانوا في تجميعات مختلفة، استخدم الاسم المؤهل بالكامل، على سبيل المثال.MyCo.MyApp.Data.CustomDataContext

  1. للتأكد من أن عناصر المصمم تعمل بشكل صحيح، انسخ سلسلة الاتصال الخاصة بك إلى ملف app.config الخاص بمكتبة الفصل الدراسي.لن يتم استخدام هذا إلا في IDE.

هذا كل شيء.

ستحتاج إلى تسمية سلسلة الاتصال الخاصة بك بنفس الاسم

ما تفعله بشكل أساسي هو إجبار سياق البيانات على تجاهل معلومات الاتصال المحددة في ملف DBML.إن استخدام أساليب ConfigurationManager يعني أنه سيلتقط سلسلة الاتصال من مجموعة الاستدعاء.

هث

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top