【问题标题】:NHibernate custom collection won't hydrateNHibernate 自定义集合不会补水
【发布时间】:2013-07-19 14:37:43
【问题描述】:

我有一个自定义集合,它包装了一个 .net HashSet 并实现了 ICollection,然后我将其映射为一个集合。我这样做是希望 NHib 能够像使用 .net HashSet 时那样使用 ICollection 接口,而不是使用 Iesi 接口 NHib 内部使用。

保存到数据库似乎工作正常,但我在补水时遇到的异常让我知道我需要做更多:

Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericSet`1[ContactMechanisms.Domain.Emails.Email]' to type 'ContactMechanisms.Domain.Emails.EmailCollection'.

These articles 经常被引用为处理自定义集合处理的方法,但链接已损坏,我可以看到更多处理使用扩展查询集合。

我必须使用 IUserCollectionType 吗?如果是这样,任何人都有显示示例实现的链接?我在当前的代码/映射中有什么愚蠢的事情吗?

什么是好的解决方案?

CODE(父实体sn-p)

public class Contact : RoleEntity<Party>, IHaveContactMechanisms
{       
    private readonly ICollection<Email> _emails = new EmailCollection();

    public virtual EmailCollection Emails { get { return (EmailCollection) _emails; } }
}

CODE(自定义集合 sn-p)

 public class EmailCollection : ContactMechanismSet<Email> { ....  }

 public class ContactMechanismSet<T> : ValueObject, ICollection<T> where T : ContactMechanism
{
    private readonly HashSet<T> _set = new HashSet<T>();
}

MAPPING(hbm值类型集合)

<set name ="_emails" table="Emails" access="field">
  <key column="ContactId"></key>
  <composite-element class="ContactMechanisms.Domain.Emails.Email, ContactMechanisms.Domain">
    <property name="IsPrimary" />
    <property name="Address" length="100"/>
    <property name="DisplayName" length="50"/>
  </composite-element>
</set>

* 更新 *

所以在我的对象设置器中执行以下操作,但是 - 我可以做得更好吗??

public virtual EmailCollection Emails {
    get {
        if (!(_emails is EmailCollection )) {
            // NHibernate is giving us an enumerable collection
            // of emails but doesn't know how to turn that into
            // the custom collection we really want
            //
            _emails = new EmailCollection (_emails );
        }
        return (EmailCollection ) _emails ;
    }
}

【问题讨论】:

  • 是否可以在 EmailCollection 实现中使用 ISet&lt;T&gt; 而不是 HashSet&lt;T&gt;

标签: nhibernate nhibernate-mapping custom-collection


【解决方案1】:

如果 EmailCollection 有一个无参数的构造函数,那么以下应该可以使用较新的 NH ootb 和较旧的注册处理 .NET ISet 的 CollectionTypeFactory(可以在互联网上找到)

public class Contact : RoleEntity<Party>, IHaveContactMechanisms
{       
    private EmailCollection _emails = new EmailCollection();

    public virtual EmailCollection Emails { get { return _emails; } }
}

public class ContactMechanismSet<T> : ValueObject, ICollection<T> where T : ContactMechanism
{
    ctor()
    {
        InternalSet = new HashSet<T>();
    }

    private ISet<T> InternalSet { get; set; }
}

<component name="_emails">
  <set name="InternalSet" table="Emails">
    <key column="ContactId"></key>
    <composite-element class="ContactMechanisms.Domain.Emails.Email, ContactMechanisms.Domain">
      <property name="IsPrimary" />
      <property name="Address" length="100"/>
      <property name="DisplayName" length="50"/>
    </composite-element>
  </set>
</component>

【讨论】:

    猜你喜欢
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多