Отображение nhibernate «многие ко многим»: почему были удалены и заново вставлены целые коллекции сумок? - PullRequest
1 голос
/ 07 января 2010

Ожидаются пользователи, профессионалы, гуру и разработчики Nhibernate.Пожалуйста, помогите !!!

Я хочу реализовать отношение: m между двумя классами.Студент посещает больше курсов, и курс состоит из большего количества студентов в качестве участников.Я делаю двунаправленную связь «многие ко многим» с сумкой, чтобы получить оба списка с каждого сайта.

Два класса для студентов и курсов:

public class Student {         
     // Attributes........

     [XmlIgnore]
     public virtual IList MyCourses { get; set; }

     // Add Method
     public virtual void AddCourse(Course c)
    {
        if (MyCourses == null)
            MyCourses = new List<Course>();

        if (!MyCourses.Contains(c))
            MyCourses.Add(c);

        if (c.Members== null)
            c.Members= new List<Student>();

        if (!c.Members.Contains(this))
            c.Members.Add(this);
    }

    public virtual void RemoveCourse(Course c)
    {
        if (MyCourses != null)
            MyCourses.Remove(c);

        if (c.Members!= null)
            c.Members.Remove(this);
    }
}

public class Course {         
     // Attributes........

     [XmlIgnore]
     public virtual IList Members { get; set; }
}

В базе данных есть две таблицы t_Student, t_Course и таблица отношений tr_StudentCourse (id, student_id, course_id).

<class name="Student" table="t_Student" polymorphism="explicit">
 ..... 
 <bag name="MyCourses" table="tr_StudentCourse">
   <key column="student_id" />
   <many-to-many class="Course" column="course_id" not-found="ignore" />
 </bag>    
</class>

<class name="Course" table="t_Course" polymorphism="explicit">
 ..... 
 <bag name="Members" table="tr_StudentCourse" inverse="true">
   <key column="course_id" />
   <many-to-many class="Student" column="student_id" not-found="ignore" />
 </bag>    
</class>

Курс был выбран как обратный в двунаправленной ассоциации.Я сделал то же самое, что и в примере (Категория, Элемент) в разделе 6.8 документации по nhibernate.Поэтому я сохранил объект студента после вставки курса в список MyCourses, вызвав метод Add / Remove.

Student st1 = new Student();
Course c1 = new Course();    
Course c2 = new Course();
st1.AddCourse(c1);
st1.AddCourse(c2);
session.saveOrUpdate(st1);

Это прекрасно работает, st1, c1 и их отношение (st1, c1) можно найти в базе данных.Наборы данных отношений (id = 1 , st1.id, c1.id) и (id = 2 , st1.id, c2.id).Затем я добавляю больше курсов к объекту st1.

Course c3 = new Course();
st1.AddCourse(c3);
session.saveOrUpdate(st1);

Я вижу 3 набора данных отношений, но два старых отношения были удалены, и новые три были созданы с другим новым идентификатором.(id = 3 , st1.id, c1.id), (id = 4 , st1.id, c2.id) и (id = 5 , st1.id, c3.id).В таблице отношений больше нет набора данных с id = 1 и 2.

То же самое, удалив, если я удалю курс из student.MyCourse, а затем сохраню объект студента.Вся коллекция была также удалена и воссоздан новый список, в котором меньше одного удаленного элементаЭта проблема приводит к очень быстрому увеличению идентификатора в таблице отношений и созданию резервных копий при создании резервной копии отношения.

Я несколько дней искал в Интернете, документации и форумах, чтобы выяснить, почему была удалена вся старая коллекция.и новый, как создается при каждом изменении, но я не был успешным.Это ошибка в отображении nhibernate или я что-то сделал не так?

Я очень очень благодарен за вашу помощь и ответ.

Документация Nhibernate http://nhforge.org/doc/nh/en/index.htm

Ответы [ 2 ]

2 голосов
/ 07 января 2010

NHibernate не может создавать, удалять или обновлять строки индивидуально, потому что нет ключа, который можно использовать для определить отдельный ряд.

По примечание из «6.2. Отображение коллекции»

Как только вы наберете id в tr_StudentCourse, вы можете попробовать использовать проиндексированные коллекции, т.е. заменить <bag> на <map> или аналогичные и добавить элемент <index> в отображение:

<index
    column="id"
    type="int"
/>

или даже создать специальный объект для таблицы отношений для использования с <index-many-to-many>.

1 голос
/ 08 января 2010

Вот что я нашел на сайте NHibernate:

Hibernate удаляет всю мою сбор и воссоздание его вместо обновления таблицы.

Это обычно происходит, когда NHibernate не могу понять, какие элементы изменились в коллекции. Общие причины:

  • замена постоянной коллекции полностью с новой коллекцией экземпляр передает NHibernate вручную построенный объект и вызов Update на нем.

  • сериализация / десериализация постоянная коллекция, по-видимому, также вызывает эту проблему.

    • обновление с обратным = "ложь" - в этом случае NHibernate не может построить SQL для обновить отдельный элемент коллекции.

Таким образом, чтобы избежать проблемы:

передать тот же экземпляр коллекции, что ты вернулся из NHibernate (не обязательно в том же сеансе), попробуйте использовать другую коллекцию вместо <bag> (<idbag> или <set>), или попробуйте использовать атрибут inverse = "true" для <bag>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...