【问题标题】:nhibernate - Create child by updating parent, or create explicitly?nhibernate - 通过更新父级或显式创建来创建子级?
【发布时间】:2015-03-17 19:13:00
【问题描述】:

创建子对象的首选方法是什么?

  1. 将子级添加到其父级的集合中并在父级上调用更新,或
  2. 显式创建子级,将子级添加到父级的集合中,然后更新父级?

我正在为#1 苦苦挣扎。我认为 #2 更可取(不那么“魔法”),这已经够难了。

【问题讨论】:

    标签: nhibernate fluent-nhibernate parent-child


    【解决方案1】:

    不确定“首选方法”是什么(可能取决于谁更喜欢)。但我可以分享我的方式

    如果父实体是根实体,那么我们应该一次性保存所有引用树:session.SaveOrUpdate(parent)

    例如Employee 拥有 Educations 的集合。在这种情况下,它应该是这样的

    1. 创建Education 给它参考员工,
    2. Add() 收藏employee.Educations
    3. 使映射反向,cascade="all-delete-orphan" ...
    4. NHibernate 将按照我们对 session.SaveOrUpdate(parent) 的期望进行操作

    xml中的一些sn-ps:

    <class name="Employee" table="..." lazy="true" 
      optimistic-lock="version" dynamic-update="true" batch-size="25" >
    
      <cache usage="read-write" region="ShortTerm"/>
      <id name="ID" column="Employee_ID" generator="native" />
    
      <bag name="Educations" lazy="true" inverse="true" 
           batch-size="25" cascade="all-delete-orphan" >
        <key column="Employee_ID" />
        <one-to-many class="Education" />
      </bag>
      ...
    

    教育

    <class name="Education" table="..." lazy="true" batch-size="25>
      <cache usage="read-write" region="ShortTerm"/>
      <id name="ID" column="Education_ID" generator="native" />
    
      <many-to-one not-null="true" name="Employee" class="Employee" 
                 column="Employee_ID" />
    ...
    

    流利:

    public class EmployeeMap : ClassMap<Employee>
    {
      public EmployeeMap()
      {
          BatchSize(25)
          ...
          HasMany(x => x.Educations)
            .AsBag()
            .BatchSize(25)
            .LazyLoad() 
            .Cascade.AllDeleteOrphan() 
            .Inverse()
            .KeyColumn("Employee_ID")
    
    public class EducationMap : ClassMap<Education>
    {
      public EducationMap()
      {
         ...
         References(x => x.Employee, "Employee_ID")
              .Not.Nullable()
              ...
    

    现在是 C# 关系:

    // business
    var employee = ...;
    var education = new Education
    {
       Employee = employee, 
       ...
    };
    employee.Educations.Add(education);
    
    // DAO
    session.SaveOrUpdate(employee);
    

    如果父级不是root,则只有一个关系EmployeeSubordinates 类型为Employee 的集合),保持持久化分开

    【讨论】:

    • 很棒的答案。我喜欢你对根/父母和关系使用不同策略的想法。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多