nhibernate 映射多对多:为什么整个包集合被删除并重新插入?

发布于 2024-08-16 18:14:25 字数 2844 浏览 11 评论 0原文

期待 Nhibernate 用户、专业人士、专家和开发人员。请帮忙!

我想实现两个类之间的关系。一个学生参加更多的课程,一个课程由更多的学生作为成员组成。我与 bag 进行多对多的双向关联,以从每个站点获取两个列表。

两个 Student 和 Course 类:

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>

在双向关联中,路线被选择为。我做了与 nhibernate 文档第 6.8 节中的示例(类别、项目)相同的操作。因此,我通过调用添加/删除方法在列表 MyCourses 中插入课程后保存了学生对象。

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 创建的。 (id=3、st1.id、c1.id)、(id=4、st1.id、c2.id) 和 (id=5< /strong>、st1.id、c3.id)。关系表中不存在 id=1 和 2 以上的数据集。

如果我从 Student.MyCourse 中删除课程,然后保存学生对象,则删除相同的内容。所有集合也被删除并重新创建一个新列表,其中少了一个已删除的元素。这个问题使得关系表中的 id 创建速度非常快,并且在进行关系备份时会遇到麻烦。

我在互联网、文档和论坛中查看了几天,以找出为什么整个旧集合被删除并通过每次更改创建新集合,但我没有成功。这是 nhibernate 映射的错误还是我做错了什么?

我非常非常感谢您的帮助和回答。

Nhibernate 文档 http://nhforge.org/doc/nh/en/index.htm< /a>

Nhibernate users, professionals, gurus and developers are expected. Please help !!!

I want to realise a n:m relation between two classes. A student attends in more courses and a course consists of more students as members. I do a bidirectional association many-to-many with bag to get the both lists from each site.

The two Student and Course classes:

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; }
}

In database there are two tables t_Student, t_Course and a relation table 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>

Course was chosen as inverse in the bidirectional association. I did the same as example (Categorie, Item) in section 6.8 of nhibernate documentation. So I saved the student object after inserting a course in the list MyCourses by calling the Add/Remove-method.

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

That works fine, the st1, c1 and their relation (st1,c1) can be find in the database. The relation datasets are (id=1, st1.id, c1.id) and (id=2, st1.id, c2.id).
Then I add more courses to the object st1.

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

I can see the 3 relation datasets, but the two old relations were deleted and new three were created with another new id. (id=3, st1.id, c1.id), (id=4, st1.id, c2.id) and (id=5, st1.id, c3.id). There are not dataset with id=1 and 2 more in relation table.

The same by deleting if I remove a course from student.MyCourse and then save the student object. All collection was also deleted and recreated a new list which less one deleted element. That problem makes the id in the relation table increates very fast and a have troble by doing a backup of relation.

I have looked some days in internet, documentation and forums to find out why the whole old collection was deleted and a new as created by each changing, but I was not successful. It is a bug from nhibernate mapping or did I do any wrong?

I am very very grateful to your help and answer.

Nhibernate documentation http://nhforge.org/doc/nh/en/index.htm

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最笨的告白 2024-08-23 18:14:25

NHibernate 无法创建、删除或
单独更新行,因为
没有可用于
识别单独的行。

通过“6.2. 映射集合”中的注释

tr_StudentCourse 中有 id 您可以尝试使用索引集合,即将 替换为

或类似的并将 元素添加到映射中:

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

甚至为关系表创建一个特殊实体以与 一起使用。

NHibernate can't create, delete or
update rows individually, because
there is no key that may be used to
identify an individual row.

By note from "6.2. Mapping a Collection"

As soon as you have id in tr_StudentCourse you can try using indexed collections, i.e. replace <bag> with <map> or similar and add <index> element to the mapping:

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

or even create a special entity for the relation table to use with <index-many-to-many>.

明月松间行 2024-08-23 18:14:25

这是我在 NHibernate 网站上找到的:

Hibernate 正在删除我的整个
收集并重新创建它
更新表格。

这通常发生在 NHibernate 时
无法弄清楚哪些项目发生了变化
在集合中。常见原因有:

  • 替换持久集合
    全新系列
    手动传递NHibernate的实例
    构造对象并调用 Update
    就在上面。

  • 序列化/反序列化
    持久收集显然也是
    导致这个问题。

    • 正在更新
      与 inverse="false" - 在这种情况下,
      NHibernate 无法构造 SQL 来
      更新单个收藏项目。

因此,为了避免这个问题:

传递相同的集合实例
你从 NHibernate 返回到它
(不一定在同一会话中),
尝试使用其他集合
而不是 ),
或尝试使用 inverse="true" 属性
对于

This is what I've found on the NHibernate website:

Hibernate is deleting my entire
collection and recreating it instead
of updating the table.

This generally happens when NHibernate
can't figure out which items changed
in the collection. Common causes are:

  • replacing a persistent collection
    entirely with a new collection
    instance passing NHibernate a manually
    constructed object and calling Update
    on it.

  • serializing/deserializing a
    persistent collection apparently also
    causes this problem.

    • updating a
      with inverse="false" - in this case,
      NHibernate can't construct SQL to
      update an individual collection item.

Thus, to avoid the problem:

pass the same collection instance that
you got from NHibernate back to it
(not necessarily in the same session),
try using some other collection
instead of <bag> (<idbag> or <set>),
or try using inverse="true" attribute
for <bag>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文