NHibernate:تعيين عمود واحد من كثير إلى واحد إلى نوع بدائي

StackOverflow https://stackoverflow.com/questions/1617701

سؤال

لدي التعيين التالية:

<set name="People" lazy="true" table="ProjectPeople">
  <key column="ProjectId" />
  <composite-element class="PersonRole">
    <many-to-one name="Person" column="PersonId" cascade="save-update" not-null="true" />
    <many-to-one name="Role" column="RoleId" cascade="save-update" not-null="true"  />
  </composite-element>
</set>

الآن أنا لا أريد حقا أن يكون فئة منفصلة عن دور في المجال ، أريد فقط اسم الدور.ومع ذلك ، في DB الأدوار يجب أن يكون لا يزال تطبيع في جدول منفصل Role (Id, Name).

كيف اعرض الخريطة حتى أن الناس استخدام التالية PersonRole الصف ؟

public class PersonRole {
    public virtual Person Person { get; set; }
    public virtual string Role { get; set; }
}

التحديث:وأضاف فضله ، يبدو السؤال مفيدة ليس فقط بالنسبة لي.

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

المحلول

وأنا شخصيا من شأنه أن يخلق فئة دور مثل ياسر

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

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

<الإضراب> ومع ذلك اتخاذ هذا النهج أعتقد أن يعني أنك لن تكون قادرا على تحديث دوركم كما هو reerencing وجهة نظر.

تعديل: لتحديث الدور الذي يمكن أن تضيف <sql-insert>,<sql-update> and <sql-delete> إلى ملف تعيين بحيث تتالي الجميع سيعمل

نصائح أخرى

أنت في الحقيقة لن تحصل على الجواب الذي الأمل, لأنه ببساطة غير ممكن.(ن)السبات هو كائن علائقي-رسم إطار الدعم ثلاثة أنواع من الخرائط الاستراتيجيات:

  • الجدول في الصف الواحد الهرمي
  • جدول لكل فئة فرعية
  • جدول لكل فئة محددة

كما أنه يسمح لك أن تحيد عن هذا باستخدام formula أو sql-insert الخ, ولكن كما كنت قد وجدت هذه فقط تسبب المزيد من الألم في النهاية لا تشجع من السبات المجتمع و هي سيئة الصيانة من التعليمات البرمجية الخاصة بك.

حل ؟

في الواقع هو بسيط جدا.كنت لا ترغب في استخدام فئة Role.أعتقد أنك تقصد أنك لا تريد أن فضح فئة من نوع الدور الذي كنت لا تريد أن يكون نوع prObject.Role.Name في كل وقت.فقط prObject.Role, التي يجب أن تعود سلسلة.لديك عدة خيارات:

  1. استخدام الطبقة الداخلية في PersonRole هذه الدرجة يمكن أن تكون داخلية أو خاصة.إضافة خاصية دور مجموعات التحديثات عضو في الميدان ؛
  2. استخدام الطبقة الداخلية.إضافة خاصية دور مجموعات التحديثات عضو في الميدان ؛

دعونا النظر في الخيار 2:

// mapped to table Role, will not be visible to users of your DAL
// class can't be private, it's on namespace level, it can when it's an inner class
internal class Role 
{
    // typical mapping, need not be internal/protected when class is internal
    // cannot be private, because then virtual is not possible
    internal virtual int Id { get; private set; }
    internal virtual string Name { get; set; }
}

// the composite element
public class PersonRole
{
    // mapped properties public
    public virtual Person Person { get; set; }

    // mapped properties hidden
    internal virtual Role dbRole { get; set; }

    // not mapped, but convenience property in your DAL
    // for clarity, it is actually better to rename to something like RoleName
    public string Role     /* need not be virtual, but can be */
    { 
        get
        {
            return this.dbRole.Name;
        }
        set
        {
            this.dbRole.Name = value;    /* this works and triggers the cascade */
        }
    }
}

و رسم الخرائط يمكن أن تبدو كما هو متوقع.النتيجة:لم تكن قد انتهكت واحدة-جدول لكل فئة القاعدة (تحرير:السائل يقول صراحة يريد أن تنتهك هذه القاعدة ، Hib يدعم ذلك ، وهو الصحيح), ولكن كنت قد الخفية الكائنات من التعديل و الوصول باستخدام نموذجي وجوه المنحى التقنيات.كل NH الميزات (تتالي الخ) لا تزال تعمل كما هو متوقع.

(ن)السبات هو كل شيء عن هذا النوع من القرارات:كيفية جعل جيدا من خلال الفكر و آمنة طبقة تجريد إلى قاعدة البيانات الخاصة بك دون التضحية الوضوح والإيجاز أو الصيانة أو انتهاك OO أو ORM القواعد.


تحديث (q بعد.تم إغلاق)

غيرها من أساليب ممتازة أنا استخدم الكثير عند التعامل مع هذا النوع من المسألة:

  • إنشاء الخاص بك تعيينات عادة (أي واحد من الدرجة في الجدول ، أنا أعلم أنك لا تحب ذلك ، ولكن هذا أفضل) و استخدام طرق الإرشاد:

     // trivial general example
     public static string GetFullName(this Person p)
     {
         return String.Format("{0} {1}", p.FirstName, p.LastName);
     }
    
     // gettor / settor for role.name
     public static string GetRoleName(this PersonRole pr)
     {
         return pr.Role == null ? "" : pr.Role.Name;
     }
     public static SetRoleName(this PersonRole pr, string name)
     {
         pr.Role = (pr.Role ?? new Role());
         pr.Role.Name = name;
     }
    
  • إنشاء الخاص بك تعيينات عادة ولكن استخدام partial classes, التي تمكنك من "تزيين" الفئة الخاصة بك في أي الطريقة التي تريد.ميزة:إذا كنت تستخدم إنشاء الخرائط من الجداول الخاصة بك, يمكنك تجديد في كثير من الأحيان كما يحلو لك.بالطبع فئات جزئية يجب أن تذهب في ملفات منفصلة حتى النظر في الخاص بك ترغب في تناقص "سخام" هذا ربما ليس سيناريو جيد حاليا.

     public partial class PersonRole
     {
         public string Role {...}
     }
    
  • ولعل أبسط:الزائد فقط ToString() بالنسبة Role, مما يجعلها مناسبة للاستخدام في String.Format والأصدقاء, ولكن بالطبع لا تجعل احالة.بشكل افتراضي, كل كيان أو الطبقة أو بوكو يجب أن يكون ToString() الزائد على أي حال.

على الرغم من أنه من الممكن أن تفعل هذا مع NHibernate مباشرة ، س.تم إغلاق قبل كان لدي الوقت للنظر في ذلك (أي منها خطأ, أنا فقط لم يكن لديك الوقت).أنا تحديث إذا كنت تجد الوقت للقيام بذلك من خلال السبات HBM رسم الخرائط ، على الرغم من أنني لا أوافق على هذا النهج.ليس من الجيد أن يتصارع مع مفاهيم متقدمة من المستدمية النزلية عندما والنتيجة النهائية هي أقل وضوحا عن غيرها من المبرمجين و أقل وضوحا العام (من أين لك هذا الجدول تذهب ؟ لماذا لم يكن هناك IDao التجريد على هذا الجدول ؟ انظر أيضا NHibernate أفضل الممارسات و S#arp).ومع ذلك ، فإن ممارسة مثيرة للاهتمام مع ذلك.

النظر في التعليقات على "أفضل الممارسات":في الحالات النموذجية, فإنه لا ينبغي أن يكون فقط "فئة واحدة في الجدول" ، ولكن أيضا واحدة IDaoXXX واحد DaoConcreteXXX واحد GetDaoXXX لكل جدول ، حيث يمكنك استخدام فئة/واجهة الهرمي التفريق بين القراءة فقط و قراءة/كتابة الجداول.هذا هو الحد الأدنى من أربعة فصول/خطوط من التعليمات البرمجية في الجدول.هذا هو عادة تلقائي ولكن يعطي واضحة جدا الوصول إلى طبقة (dao) إلى طبقة البيانات (الدال).طبقة البيانات هو خير وأبقى كما المختلف ممكن.لا شيء من هذه "أفضل الممارسات" منع استخدام طرق الإرشاد أو الجزئي طرق الانتقال Role.Name في Role.

هذه هي أفضل العامة الممارسات.انها ليست دائما ممكنة أو مجدية أو حتى ضرورية في بعض أو خاصة أو نموذجية sitations.

وأنا لا أعتقد أنه من الممكن تعيين كثير من واحد إلى نوع بدائي لو كنت أنت وأود إضافة فئة دور للنموذج

وهذه أكبر بدوره الخروج من الأمر كله OO خالصة. من المؤكد أن الهدف هو أن يكون هناك تطبيق العمل. لا somebodies نسخة من التسلسل الهرمي فئة الكمال. وذلك ما إذا كان لديك رمز "prObject.Role.Name" بدلا من "prObject.Role". كيف هذا سوف تساعدك على جعل البرنامج أكثر موثوقية أفضل؟

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

إذا كنت حقا لا يكون لها "دور واحد فقط لكل شخص" القاعدة ثم فإنه ينبغي أن refleced في نموذج البيانات الأساسية.

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