nhibernate继承映射问题

时间:2011-07-21 13:26:34

标签: nhibernate inheritance mapping

我改变了Party&的关系。 PartyName是单向的,测试现在通过。

但我确实对最终测试输出有疑问:

当测试保存学生时,它会保存一个Party,然后插入与PartyName的级联关系。大。

最后,当它取出学生时,它会完成最终的SELECT。

但是在最终的SELECT之前和刚刚进入PartyName的初始INSERT之后就是这个更新:

NHibernate: 
UPDATE PartyNames SET TheRequiredName = @p0, EverythingElse = @p1, ContextUsed = @p2, Salutation = @p3, EffectiveStart = @p4, EffectiveEnd = @p5 
WHERE PartyNameId = @p6;@p0 = 'Hesh' [Type: String (0)], @p1 = 'Berryl;;;' [Type: String (0)], @p2 = 'student' [Type: String (0)], @p3 = NULL [Type: String (0)], @p4 = NULL [Type: DateTime (0)], @p5 = NULL [Type: DateTime (0)], @p6 = 65536 [Type: Int32 (0)]

我不遵循它为什么这样做。什么是触发UPDATE?

干杯,
Berryl

MAPPING

 <class name="Party" table="Parties">
<id name="Id">
  <column name="PartyId" />
  <generator class="hilo" />
</id>

<discriminator column="Type" not-null="true" type="string" />

<set access="field.camelcase-underscore" cascade="all" inverse="true" name="Names">
  <key foreign-key="Party_PartyName_FK">
    <column name="PartyNameId" />
  </key>
  <one-to-many class="Parties.Domain.Names.PartyName, Parties.Domain" />
</set>

<subclass 
  name="Student, Core.TestingSupport" 
  discriminator-value="Student"
  >
  <property name="Number" />

  <many-to-one 
    class="Course, Core.TestingSupport" 
    foreign-key="Course_FK" 
    name="Course">
    <column name="SomeDopeyClassId" index="CourseIndex" />
  </many-to-one>
</subclass>

                            

<property name="TheRequiredName" not-null="true" length="50"/>
<property name="EverythingElse" />
<property name="ContextUsed" length="50"/>
<property name="Salutation" length="20"/>
<property name="EffectivePeriod" type="Core.Data.NHibernate.UserTypes.DateRangeUserType, Core.Data">
  <column name="EffectiveStart"/>
  <column name="EffectiveEnd"/>
</property>

对象模型代码

public class Party : Entity
{           
    ...

    /// <summary>One or more optional names.</summary>
    public virtual IEnumerable<PartyName> Names { get { return _names; } }

    private readonly ICollection<PartyName> _names = new HashSet<PartyName>();

    public virtual void AddPartyName(PartyName partyName)
    {
        if (partyName == null) throw new ArgumentNullException("partyName");

        _names.Add(partyName);
    }

    public virtual bool RemovePartyName(PartyName partyName)
    {
        if (partyName == null) throw new ArgumentNullException("partyName");

        return _names.Remove(partyName);
    }     
}

public class Student : Party
{
    private const string _context = "student";

    public virtual PersonName StudentName {
        get { return (PersonName)this.GetNameForContextOf(_context); } 
        set { this.SetPartyName(value, _context); }
    }

    ...
}

public static class PartyNameExtensions
{
    public static void SetPartyName(this Party party, PersonName personName, string contextUsed) {
        if (party == null) throw new ArgumentNullException("party");
        if (string.IsNullOrWhiteSpace(contextUsed)) throw new ArgumentNullException("contextUsed");

        var found = party.GetNameForContextOf(contextUsed);
        if (personName == null)
        {
            if (found != null) party.RemovePartyName(found);
        }
        else {
            if (found == null)
            {
                var partyName = (PartyName)personName;
                partyName.ContextUsed = contextUsed;
                party.AddPartyName(partyName);
            }
        }
    }

    public static PartyName GetNameForContextOf(this Party party, string contextUsed) {
        if (party == null) throw new ArgumentNullException("party");
        if (string.IsNullOrEmpty(contextUsed)) throw new ArgumentNullException("contextUsed");

        return party.Names.SingleOrDefault(x => x.ContextUsed == contextUsed);
    }
}

传递测试(和输出)

    [Test]
public void CanSaveAndLoad_Names()
{
    _student = new Student { StudentName = NameSeeds.DevPersonName, };
    using (var tx = _session.BeginTransaction())
    {
        _session.Save(_student);
        tx.Commit();
    }
    _session.Clear();

    Student foundStudent;
    using (var tx = _session.BeginTransaction())
    {
        foundStudent = _session.Get<Student>(_student.Id);
        tx.Commit();
    }
    Assert.That(_student.StudentName, Is.EqualTo(NameSeeds.DevPersonName));
}

输出

NHibernate: select next_hi from hibernate_unique_key
NHibernate: update hibernate_unique_key set next_hi = @p0 where next_hi = @p1;@p0 = 2 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)]
NHibernate: select next_hi from hibernate_unique_key
NHibernate: update hibernate_unique_key set next_hi = @p0 where next_hi = @p1;@p0 = 3 [Type: Int32 (0)], @p1 = 2 [Type: Int32 (0)]
NHibernate: INSERT INTO Parties (Number, CourseId, Type, PartyId) VALUES (@p0, @p1, 'Student', @p2);@p0 = 0 [Type: Int32 (0)], @p1 = NULL [Type: Int32 (0)], @p2 = 32768 [Type: Int32 (0)]
NHibernate: INSERT INTO PartyNames (TheRequiredName, EverythingElse, ContextUsed, Salutation, EffectiveStart, EffectiveEnd, PartyNameId) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 'Hesh' [Type: String (0)], @p1 = 'Berryl;;;' [Type: String (0)], @p2 = 'student' [Type: String (0)], @p3 = NULL [Type: String (0)], @p4 = NULL [Type: DateTime (0)], @p5 = NULL [Type: DateTime (0)], @p6 = 65536 [Type: Int32 (0)]
NHibernate: UPDATE PartyNames SET TheRequiredName = @p0, EverythingElse = @p1, ContextUsed = @p2, Salutation = @p3, EffectiveStart = @p4, EffectiveEnd = @p5 WHERE PartyNameId = @p6;@p0 = 'Hesh' [Type: String (0)], @p1 = 'Berryl;;;' [Type: String (0)], @p2 = 'student' [Type: String (0)], @p3 = NULL [Type: String (0)], @p4 = NULL [Type: DateTime (0)], @p5 = NULL [Type: DateTime (0)], @p6 = 65536 [Type: Int32 (0)]
NHibernate: SELECT student0_.PartyId as PartyId2_0_, student0_.Number as Number2_0_, student0_.CourseId as SomeDope4_2_0_ FROM Parties student0_ WHERE student0_.PartyId=@p0 and student0_.Type='Student';@p0 = 32768 [Type: Int32 (0)]

0 个答案:

没有答案