سؤال

أنا حاليا باستخدام NHibernate بلدي طبقة الوصول إلى البيانات باستخدام بطلاقة NHibernate لإنشاء الخرائط الملفات بالنسبة لي.لدي اثنين من الطبقات ، TripItem و TripItemAttributeValue ، والتي لها عدة العلاقة بينهما.

يتم التعيين على النحو التالي:

public class TripItemMap : ClassMap<TripItem2>
{
    public TripItemMap()
    {
        WithTable("TripItemsInt");
        NotLazyLoaded();

        Id(x => x.ID).GeneratedBy.Identity().WithUnsavedValue(0);
        Map(x => x.CreateDate, "CreatedOn").CanNotBeNull();
        Map(x => x.ModifyDate, "LastModified").CanNotBeNull();

        /* snip */

        HasManyToMany<TripItemAttributeValue>(x => x.Attributes).AsBag()
            .WithTableName("TripItems_TripItemAttributeValues_Link")
            .WithParentKeyColumn("TripItemId")
            .WithChildKeyColumn("TripItemAttributeValueId")
            .LazyLoad();
    }
}

public class TripItemAttributeValueMap : ClassMap<TripItemAttributeValue>
{
    public TripItemAttributeValueMap()
    {
        WithTable("TripItemAttributeValues");

        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).CanNotBeNull();

        HasManyToMany<TripItem2>(x => x.TripItems).AsBag()
            .WithTableName("TripItems_TripItemAttributeValues_Link")
            .WithParentKeyColumn("TripItemAttributeValueId")
            .WithChildKeyColumn("TripItemId")
            .LazyLoad();
    }
}

في بعض نقطة في طلبي أحضر القائمة سمات من قاعدة البيانات ، إضافة إلى tripItem.سمات ثم حفظ tripItem الكائن.في النهاية TripItems_TripItemAttributeValues_link لم يحصل أي سجلات جديدة ، مما أدى إلى العلاقات كونها لا تزال قائمة.

إذا لم تساعد هذه الخرائط الملفات التي تم إنشاؤها بواسطة بطلاقة NHibernate لهذه الفئات:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="ETP.Core" namespace="ETP.Core.Domain">
  <class name="TripItem2" table="TripItemsInt" xmlns="urn:nhibernate-mapping-2.2" lazy="false">
    <id name="ID" column="ID" type="Int32" unsaved-value="0">
      <generator class="identity" />
    </id>
    <property name="CreateDate" column="CreatedOn" type="DateTime" not-null="true">
      <column name="CreatedOn" />
    </property>
    <property name="ModifyDate" column="LastModified" type="DateTime" not-null="true">
      <column name="LastModified" />
    </property>
    <bag name="Attributes" lazy="true" table="TripItems_TripItemAttributeValues_Link">
      <key column="TripItemId" />
      <many-to-many column="TripItemAttributeValueId" class="ETP.Core.Domain.TripItemAttributeValue, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>

و

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="ETP.Core" namespace="ETP.Core.Domain">
  <class name="TripItemAttributeValue" table="TripItemAttributeValues" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="Id" type="Int32">
      <generator class="identity" />
    </id>
    <property name="Name" column="Name" length="100" type="String" not-null="true">
      <column name="Name" />
    </property>
    <bag name="TripItems" lazy="true" table="TripItems_TripItemAttributeValues_Link">
      <key column="TripItemAttributeValueId" />
      <many-to-many column="TripItemId" class="ETP.Core.Domain.TripItem2, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>

ماذا أفعل الخطأ هنا ؟

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

المحلول

@efdee

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

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

دعونا نقول لدي هذه الكيانات في كثير إلى كثير من العلاقة :


partial class Contact
{
   public string ContactName {get; set;}
   public IList Locations {get; set;}

}

partial class Location
{
   public string LocationName {get; set;}
   public string LocationAddress {get;set;}
   public IList Contacts {get;set;}
}

عندما أقوم بإضافة إلى موقع الاتصال.مواقع يجب أن تأكد من أن الاتصال موجود أيضا داخل الموقع.جهات الاتصال.

لذا لإضافة الموقع علي هذا الأسلوب داخل جهاز الاتصال الدرجة.


public void AddLocation(Location location)
        {
            if (!location.Contacts.Contains(this))
            {
                location.Contacts.Add(this);
            }
            Locations.Add(location);
        }

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

هذا هو بعد أن أشار لي إلى التحقق من كل من مجموعات: http://www.coderanch.com/t/217138/Object-Relational-Mapping/link-table-of-ManyToMany-annotation

نصائح أخرى

اتصل الدورة.دافق() أو استخدام المعاملات.

لست متأكدا كيف يمكنك أن تفعل ذلك مع يجيد NHibernate ولكن تحتاج إلى تعيين تتالي الخيار على حقيبة (TripItems).كالعادة ، Ayende لديه مفيدة بعد عن تتالي الخيارات.

من جوجل سريع, أقترح:

HasManyToMany<TripItem2>(x => x.TripItems).AsBag()
        .WithTableName("TripItems_TripItemAttributeValues_Link")
        .WithParentKeyColumn("TripItemAttributeValueId")
        .WithChildKeyColumn("TripItemId")
        .LazyLoad()
/*-->*/ .Cascade.All(); /*<-- this is the bit that should make it work */

أنا أيضا لدي نفس المشكلة - الانضمام إلى بيانات عدة لا تزال قائمة.كنت قد نسخت الخرائط من أخرى كثيرة إلى علاقة واحدة (موديفيد ذلك لمدة عدة rel) ولكن الاحتفاظ معكوس="true" السمة.عندما تتم إزالة هذه السمة المشكلة تم حلها.

كمب ديفيد لديه الحق:كنت ترغب في إضافة سلسلة حقيبة الخاص بك.

لطالما تحرير جهة (و من ناحية خلق) رسم الخرائط الملفات بلدي الميل الطبيعي هو وضعه هناك.يمكنك القيام بذلك على النحو التالي:

<bag name="TripItems" lazy="true" table="TripItems_TripItemAttributeValues_Link" cascade="all">
  <key column="TripItemAttributeValueId" />
  <many-to-many column="TripItemId" class="ETP.Core.Domain.TripItem2, ETP.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>

لقد وجدت أن حفظ دروسي 'نقية' و حفظ كل شيء للقيام مع nHibernate في .hbm.xml الملف يبقى الحل النظيف.بهذه الطريقة, إذا كان هناك جديد ORM البرمجيات أريد استخدام, فقط استبدال ملفات الخرائط, و لا كتابة فصول.نستخدم وحدة الاختبارات اختبار الطبقات تعطي قابلية الاختبار إلى xml ، على الرغم من أنني لا أشبه بطلاقة NHibernate أساليب.

أنا أعاني من نفس المشكلة ولكن لقد تم استخدام NHibernate.JetDriver.حاولت استخدام الموصى بها الإجابة من دون أي نجاح.لا أحد يعرف إذا كان NHibernate.JetDriver وجود قيود فيما يتعلق كثير إلى كثير ؟

هنا هي بلدي hbm الملفات في حالة شخص ما يحدث أن تكون مهتمة في استعراض لهم لحظة:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Ace.Docs.Core.Domain" assembly="Ace.Docs.Core">
<class name="Ace.Docs.Core.Domain.Address, Ace.Docs.Core" table="Addresses" lazy="true">
    <id name="Id" column="ID">
        <generator class="identity" />
    </id>
    <property name="Address1" column="Address1" />
    <property name="Address2" column="Address2" />
    <property name="City" column="City" />
    <property name="EmailAddress" column="EmailAddress" />
    <property name="Phone1" column="Phone1" />
    <property name="Phone2" column="Phone2" />
    <property name="PostalCode" column="PostalCode" />
    <property name="StateOrProvince" column="StateOrProvince" />
    <many-to-one name="AddressTypeMember" column="AddressTypeID" class="AddressType" />
    <bag name="HasPersonalInfo" table="Link_PersonalInfo_Addresses" lazy="true" cascade="save-update" inverse="true" >
        <key column="AddressID"></key>
        <many-to-many column="PersonalInfoID" class="PersonalInfo" />
    </bag>
</class>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Ace.Docs.Core.Domain" assembly="Ace.Docs.Core">
<class name="Ace.Docs.Core.Domain.PersonalInfo, Ace.Docs.Core" table="PersonalInfo" lazy="true">
    <id name="Id" column="ID">
        <generator class="identity" />
    </id>
    <property name="Prefix" column="Prefix" />
    <property name="FirstName" column="FirstName" />
    <property name="MiddleName" column="MiddleName" />
    <property name="LastName" column="LastName" />
    <property name="SIN" column="SIN" />
    <property name="Birthdate" column="Birthdate" />
    <property name="Note" column="Notes" />
    <bag name="HasAddress" table="Link_PersonalInfo_Addresses" lazy="true" cascade="save-update" inverse="true" >
        <key column="PersonalInfoID"></key>
        <many-to-many column="AddressID" class="Address" />
    </bag>
</class>

لقد حصلت عليه و آمل أن يساعد هذا شخص آخر هناك.المشكلة هي أن لدي معكوس='true' على كل الحقائب.إذا كنت قراءة المقتطف أدناه عليك ملاحظة أن هناك حاجة إلى أن يكون معكوس تعيين إلى true على واحد فقط من أكياس:

لاحظ استخدام معكوس="صحيح".مرة أخرى, هذا الإعداد يحكي NHibernate تجاهل التغييرات التي تم إجراؤها على فئات جمع واستخدام الآخر من جمعية - مجموعة العناصر - كما أن التمثيل يجب أن تكون متزامنة مع قاعدة البيانات.

أخشى تتالي.كل() ليست في الحقيقة حل مشكلتي - كان واحدا من الأشياء التي حاولت.المشكلة ليست أن العناصر المضافة إلى جمع لا يتم حفظ -- هم بالفعل في قاعدة البيانات في وقت يتم إضافتها إلى المجموعة.انها مجرد أن الإدخالات في رابط الجدول لم يتم إنشاؤه.وعلاوة على ذلك أعتقد أن تتالي.كل() من شأنه أيضا أن يسبب الطفل البنود التي سيتم حذفها ، والتي هي غير مرغوب فيه من السلوك في السيناريو.لقد حاولت استخدام سلسلة.SaveUpdate(), ولكن كما قلت قد أشار إلى هذا يحل ما هو ليس حقا مشكلتي :-)

ومع ذلك, للتأكد, سوف أعد هذا الحل وتتيح لك معرفة النتيجة.

أما بالنسبة لحفظ الطبقات نقية بنسبة 100 ٪ وهذا هو الحال مع يجيد NHibernate.الطبقة تعيينات خلق لكم هي C# كود الملفات التي تذهب جنبا إلى جنب مع كيان الطبقات إلى حد كبير مثل .hbm.xml ملفات شأنه.

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

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