سؤال

أنا أستخدم Fluent-Nhibernate (مع Automing) لإنشاء الجداول الخاصة بي ولكن أرغب في اختيار فهرس مختلف عن حقل المعرف الذي يتم استخدامه افتراضيًا. كيف يمكنك إنشاء فهارس مجمعة مع nhibernate بطلاقة على حقل بخلاف حقل المفتاح الأساسي الافتراضي؟

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

كما نعلم جميعًا ، يعد إلحاق السجلات في نهاية الجدول عملية أرخص بكثير من إدراج السجلات داخل الجدول. أيضا ، يتم تخزين السجلات في الجدول جسديًا بترتيب العناصر الموجودة في الفهرس المجمع. نظرًا لأن GUIDS "عشوائي" إلى حد ما وليست متسلسلة ، فقد يتم إنشاء GUIDs الجديدة التي لا تقل عن قيمة المعرفات الأخرى في الجدول بالفعل-وهناك التوازن في إدراج الجدول بدلاً من إلحاقها.

لتقليل هذا ، لدي عمود يسمى CreateOn وهو من نوع DateTime. أحتاج إلى تجميع الجدول على هذا العمود الذي تم إنشاؤه بحيث يتم إلحاق جميع السجلات الجديدة بدلاً من إدراجها.

أي أفكار لكيفية تحقيق هذا موضع ترحيب !!!

ملاحظة: أدرك أنه يمكنني استخدام GUIDs المتسلسلة ولكن أفضل عدم السير في هذا المسار لأسباب أمنية.


ملاحظة: ما زلت لا أملك إجابة لهذا المنشور ، لكن لدي بعض الأفكار التي أفكر فيها في الوقت الحالي.

  1. باستخدام nhibernate بدون بطلاقة ، أعتقد أنه قد يكون من الممكن إنشاء فهارس مجمعة مباشرة في nhibernate. لا أعرف بعد ما يكفي عن nhibernate لمعرفة كيفية القيام بذلك. أنا فقط جميلة (كما في تقريبا تقريبا) يمكن القيام بها.

  2. تستخدم Fluent-Nhibernate لتضمين طريقة لتعيين السمات (مثل فهرس متكاسية) على كائن SQL قبل إعادة الكتابة الأخيرة. الآن يبدو أن هذا الخيار قد اختفى. ربما سأقوم بنشر سؤال في مكان ما لمعرفة ما إذا كان هذا الخيار لا يزال متاحًا. إذا كان الأمر كذلك ، فربما يمكنني استخدام ذلك لتعيين الفهرس المجمع.

  3. يوفر Fluent-Nhibernate القدرة على فضح تكوين للتحرير اليدوي بمجرد بناؤه بطلاقة. لم أجرب هذه الوظيفة ، لكنني أتوقع أن توفر مستوى التفاصيل اللازمة لوضع فهارس مجمعة.

  4. أسوأ سيناريو ، يمكنني كتابة برنامج نصي SQL لتغيير الفهارس المجمعة على جميع طاولاتي بمجرد إنشائها. ومع ذلك ، لدي بعض الأسئلة المتعلقة بهذا النهج. A. بما أنني أستخدم توليد المخططات التلقائية ، فهل يغير NHibernate "تراجع" فهرس التجميع الخاص بي في المرة التالية التي يقيم فيها التكوين؟ 2. هل سيخطئ Nhibernate إذا اكتشف أن الفهرس المجمع قد تم تغييره؟ أحتاج إلى اختبار هذا ولكن لم أفعل ذلك بعد. أنا حقا أكره هذا الحل رغم ذلك. أنا أختبر DB ضد SQLServer2008 و MySQL. جزء من جمال Nhibernate هو أنه قاعدة بيانات غير ملائمة. بمجرد تقديم البرامج النصية ، يتم إيقاف جميع الرهانات.

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

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

المحلول

هذا منشور قديم ، لكنني آمل أن يساعد شخص آخر. هذا يأتي من تجربتي على خادم MS SQL. أعتقد أن المنصات المختلفة تتطلب حلولًا مختلفة ، ولكن يجب أن تكون هذه نقطة انطلاق جيدة.

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

الطريقة الوحيدة التي وجدتها لإنجاز هذا هي إنشاء لهجة مخصصة ، والتجاوز propery justkeystring. يأتي الافتراضي لـ Nhibernate لهجة:

    public virtual string PrimaryKeyString
    {
        get { return "primary key"; }
    }

لخادم SQL

    public override string PrimaryKeyString
    {
        get { return "primary key nonclustered"; }
    }

سيؤدي ذلك إلى إجبار SQL Server على إنشاء مفتاح أساسي غير متكامل. يمكنك الآن إضافة الفهرس المجمع الخاص بك على العمود المفضل لديك من خلال العلامة في ملف تعيين XML.

<database-object>
  <create>
    create clustered index IX_CustomClusteredIndexName on TableName (ColumnName ASC)
  </create>
  <drop>
    drop index IX_CustomClusteredIndexName ON TableName
  </drop>
</database-object>

نصائح أخرى

لا يمكنني الإجابة على ذلك على وجه التحديد ، لكنني سأعطيك بعض معلومات قاعدة البيانات منذ أن أنا هنا.

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

كما قلت نفسك ، هناك خيار آخر يتمثل في التبديل إلى استراتيجية توليد معرف GUID.comB حيث تعتمد PK UIDs على جزء يعد GUID وجزءًا يضمن أن تكون المعرفات التي تم إنشاؤها متتابعًا.

تحقق من مزيد من المعلومات في منشور من قبل جيفري باليرمو هنا.

لكنك ذكرت أنه لا تريد القيام بذلك لأسباب أمنية - لماذا هذا؟

تمامًا كما قال @ABX78 ، هذا منشور قديم ، لكنني أود أن أشارك معرفتي في حل لهذه المشكلة أيضًا. لقد قمت ببناء حل للفكرة 3 "يعرض Nhibernate بطلاقة التعيينات":

بعد إنشاء التكوين (وبالتالي يتم تحليل التعيينات) ، فإن Nhibernate بطلاقة يعطينا Oppertunity للنظر في التعيينات الفعلية مع configuration.ClassMappings و configuration.CollectionMappings. يتم استخدام هذا الأخير في المثال أدناه لتعيين مفتاح أساسي مركب مما أدى إلى فهرس متجمع في SQL Server (كما يشير @ABX78):

foreach (var collectionMapping in configuration.CollectionMappings) {
    // Fetch the columns (in this example: build the columns in a hacky way)
    const string columnFormat = "{0}_id";
    var leftColumn = new Column(string.Format(
        columnFormat,
        collectionMapping.Owner.MappedClass.Name));
    var rightColumn = new Column(string.Format(
        columnFormat,
        collectionMapping.GenericArguments[0].Name));
    // Fetch the actual table of the many-to-many collection
    var manyToManyTable = collectionMapping.CollectionTable;
    // Shorten the name just like NHibernate does
    var shortTableName = (manyToManyTable.Name.Length <= 8)
                                ? manyToManyTable.Name
                                : manyToManyTable.Name.Substring(0, 8);
    // Create the primary key and add the columns
    // >> This part could be changed to a UniqueKey or to an Index
    var primaryKey = new PrimaryKey {
        Name = string.Format("PK_{0}", shortTableName),
    };
    primaryKey.AddColumn(leftColumn);
    primaryKey.AddColumn(rightColumn);
    // Set the primary key to the junction table
    manyToManyTable.PrimaryKey = primaryKey;
    // <<
}

مصدر: Nhibernate بطلاقة: كيفية إنشاء فهرس متكامل على طاولة انضمام إلى العديد من العدد؟

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