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"
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。