我正在使用 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
属性之前,代理的 role
字段确实有一个填充集合。
public class DefaultDynamicLazyFieldInterceptor
: IFieldInterceptorAccessor, Proxy.DynamicProxy.IInterceptor
{
...
public object Intercept(InvocationInfo info)
{
var methodName = info.TargetMethod.Name;
if (FieldInterceptor != null)
{
...
检查 InvocationInfo
实例时,proxy
和 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, MyAssembly, Version=1.0.0.0, Culture=neutral, 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, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
table="Roles">
...
</class>
</hibernate-mapping>
最佳答案
尝试使用
bag access="field.camelcase"
代替
bag access="nosetter.camelcase"
关于c# - NHibernate 3.2 集合属性为空,而支持字段包含项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6661922/