c# - NHibernate 3.2 集合属性为空,而支持字段包含项目

标签 c# .net nhibernate nhibernate-mapping

我正在使用 NHibernate 3.2,但在映射集合时遇到了问题。

查询用户账户后...

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

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

Debugger view

这是 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 实例时,proxyTarget 实例确实具有角色 字段,包含填充的集合。

编辑 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/

相关文章:

c# - NHibernate QueryOver 选择只需要的模型

c# - 如何引用 UDF 中的一系列单元格

c# - 不可为 null 的属性为 null

c# - 为产品发布禁用 Serilog

c# - 列表框滚动条不跟随所选项目(使用 ICollectionView)

c++ - 如何在 Qt 中使用 .NET Framework 中的系统命名空间?

c# - 建模 NHibernate 查询

c# - Kendo UI Grid 在调用读取后未填充

.NET Core MSTest 参数

nhibernate - 防止 NHibernate 将属性映射到代理