加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – NHibernate 3.2集合属性为空,而后备字段包含项目

发布时间:2020-12-15 21:20:45 所属栏目:百科 来源:网络整理
导读:我正在使用NHibernate 3.2,我在映射集合时遇到问题. 查询用户帐户后… UserAccount userAccount = (from u in Session.QueryUserAccount() where u.Username == username select u).SingleOrDefault(); … Role属性包含空集合,而roles字段包含实际项目: 这
我正在使用NHibernate 3.2,我在映射集合时遇到问题.

查询用户帐户后…

UserAccount userAccount = (from u in Session.Query<UserAccount>()
                           where u.Username == username
                           select u).SingleOrDefault();

… Role属性包含空集合,而roles字段包含实际项目:

这是NH 3.2中的一个错误还是什么?我很确定它在3.1上有效.

我认为代理行为可能有问题,特别是处理Roles属性的延迟加载的覆盖.但是,我不知道如何检查生成的代理类(使用IL反编译器),因为据我所知,它只在运行时存在于内存中.

编辑1

为了帮助我找出代理内部发生了什么,我刚刚发布了这个问题:Is there a way to decompile the proxy classes that are generated by NHibernate?.我认为该主题本身应该是一个问题,因为它可能在许多其他情况下使用.

编辑2

好吧,我设法反编译动态代理类.这是管理Roles属性的延迟加载的方法:

public override IEnumerable<Role> get_Roles()
{
    IInterceptor interceptor = this.Interceptor;
    if (interceptor == null)
    {
        throw new NotImplementedException();
    }

    object[] args = new object[0];

    InvocationInfo info = new InvocationInfo(
        this,(MethodInfo)methodof(UserAccount.get_Roles),null,new Type[0],args);

    args = info.Arguments;
    return (IEnumerable<Role>)interceptor.Intercept(info);
}

我不认为这里有什么特别之处.

编辑3

在调试拦截器时(部分显示在下面),我注意到当它为methodName ==“get_Roles”调用时,对于TargetInstance属性(在这种情况下是UserAccount),它的roles字段是一个空集合.在访问代理实例上的Roles属性之前,代理的角色字段确实具有填充的集合.

public class DefaultDynamicLazyFieldInterceptor
    : IFieldInterceptorAccessor,Proxy.DynamicProxy.IInterceptor
{
    ...
    public object Intercept(InvocationInfo info)
    {
        var methodName = info.TargetMethod.Name;

        if (FieldInterceptor != null)
        {
            ...

检查InvocationInfo实例时,代理和Target实例确实有一个角色字段,其中包含已填充的集合.

编辑4

我想我已经遇到了NH Issue 2772 – Lazy-collection not loaded when a property is Lazy-loaded.

结束编辑

这是实体类:

public class UserAccount : Entity
{
    ...
    private IList<Role> roles;

    public virtual IEnumerable<Role> Roles
    {
        get
        {
            return roles;
        }
    }
    ...
}

public class Role : Entity
{
    ...
}

以下是UserAccount映射的HBM映射文件的一部分:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" 
                   auto-import="false" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true"
         dynamic-update="true" schema="[MySchema]" mutable="true"
         name="MyNamespace.UserAccount,MyAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"
         table="UserAccounts">
    ...
    <bag access="nosetter.camelcase" cascade="none" name="Roles"
         schema="[MySchema]" table="UserAccounts_Roles" mutable="true">
      <key>
        <column name="UserAccountId" />
      </key>
      <many-to-many class="MyNamespace.Role,PublicKeyToken=null">
        <column name="RoleId" />
      </many-to-many>
    </bag>
    ...
  </class>
</hibernate-mapping>

这是HBM的一部分,它指定了角色映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property"
                   auto-import="false" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true"
         dynamic-update="true" schema="[MySchema]" mutable="true"
         name="MyNamespace.Role,PublicKeyToken=null"
         table="Roles">
    ...
  </class>
</hibernate-mapping>

解决方法

尝试使用

bag access="field.camelcase"

代替

bag access="nosetter.camelcase"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读