C# Fluent NHibernate参考资料打印“__“拦截器”;对象而不是域对象

C# Fluent NHibernate参考资料打印“__“拦截器”;对象而不是域对象,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,在.NETWebAPI项目中,我有两个名为User和Role的简单类 用户类是: public class User { public virtual int Id { get; set; } public virtual int RoleId { get; set; } public virtual string Name { get; set; } public virtual Role Role{ get; set; } public User()

在.NETWebAPI项目中,我有两个名为User和Role的简单类

用户类是:

public class User
{
    public virtual int Id { get; set; }
    public virtual int RoleId { get; set; }
    public virtual string Name { get; set; }
    public virtual Role Role{ get; set; }

    public User() { }
}
public class Role
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    public Role() { }
}
角色类别为:

public class User
{
    public virtual int Id { get; set; }
    public virtual int RoleId { get; set; }
    public virtual string Name { get; set; }
    public virtual Role Role{ get; set; }

    public User() { }
}
public class Role
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    public Role() { }
}
使用fluent的映射包括:

用户:

角色:

这是用户和角色之间的单向关系。用户有一个角色。虽然角色可以存在于许多用户中,但在本例中,在Role类中表示该角色并不有趣

当我从数据库中获取用户时,属性“Role”获取了错误的值。应该是:

{
    "Id" : "2",
    "RoleId" : "1",
    "Name" : "Any",
    "Role": {
        "Id": "1",
        "Name" : "Any"
    }
}
但它得到了:

{
    "Id" : "2",
    "RoleId" : "1",
    "Name" : "Any",
    "Role": {
        "__interceptor": {
              "persistentClass": "NameSpaceForClass, , Version=1.0.0.0 [...]
              "getIdentifierMethod": {
        [...]
      },
}
观察NHibernate执行的SQL命令的控制台,没有调用检索角色记录的命令

那么,我错过了什么?为什么没有根据类角色的域定义正确获取类角色

更新:

多亏了Radim Köhler的回答,我意识到问题不在于流利的NHibernate,而在于“懒散”

根据他的提示,我发现了两个新错误:

第一:

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'
以及内部:

Could not initialize proxy - no Session.
我在每个操作范围中使用会话,这意味着会话在操作开始时开始,在操作结束时结束。从那以后,我开始尝试几种方法来理解为什么会话在Json序列化之前关闭。很多配置之后,我注意到在调试模式下,一切都很好。这很奇怪

不管怎样,我哪儿也去不了,所以我决定关闭懒散模式,如下所示:

References(x => x.Role).Column("rol_id").ReadOnly().Not.LazyLoad();
这不是解决办法。但是解决了这个问题,而我却一直在寻找为什么会话只能在调试模式下工作。

检查这些

接下来,介绍您自己的合同解析器

public class NHibernateContractResolver : DefaultContractResolver
{
  protected override JsonContract CreateContract(Type objectType)
  {
      if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
          return base.CreateContract(objectType.BaseType);
      else
          return base.CreateContract(objectType);
  }
}
诀窍是。。。我们使用
基类型
,这是如何从代理陷阱中获取的方法

检查这些

接下来,介绍您自己的合同解析器

public class NHibernateContractResolver : DefaultContractResolver
{
  protected override JsonContract CreateContract(Type objectType)
  {
      if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
          return base.CreateContract(objectType.BaseType);
      else
          return base.CreateContract(objectType);
  }
}

诀窍是。。。我们使用
基类型
,这是从代理陷阱中获取的方法。好吧,经过一些重构,我想出了一个解决方案

让我们回顾一下

我以为问题出在NHibernate映射上,但我错了,它们很棒,工作很好。真正的问题在于NHibernate映射提供的集合中代理对象的JSON序列化

其中一个解决方案是创建一个定制的契约解析器,教NHibernate像对待基类一样对待子对象。这确实有效,但却导致了另一个问题,这次是一个“无会话限制”的问题

经过一番挣扎和思考,我选择通过创建一个新层作为数据传输来改变我的WebAPI解决方案的体系结构。因此,我只发送等效的DTO(数据传输对象),而不是将实体发送到浏览器

为了在实体和它的DTO等价物之间进行映射,我使用AutoMapper。使用这种方法,当JSON序列化发生时,对象将设置其所有属性,并且不再依赖于NHibernate代理对象

就代码而言,我所做的是:

配置自动映射器:

Mapper.Initialize(cfg => cfg.CreateMap<User, UserDto>());
Mapper.Initialize(cfg => cfg.CreateMap<Role, RoleDto>());
执行以下分析:

IList<RoleDto> dtoList = Mapper.Map<RoleDto>(listOfUsers);
IList dtoList=Mapper.Map(ListoUsers);

就这样。JSON序列化不再有麻烦了。

好吧,经过一些重构,我想出了一个解决方案

让我们回顾一下

我以为问题出在NHibernate映射上,但我错了,它们很棒,工作很好。真正的问题在于NHibernate映射提供的集合中代理对象的JSON序列化

其中一个解决方案是创建一个定制的契约解析器,教NHibernate像对待基类一样对待子对象。这确实有效,但却导致了另一个问题,这次是一个“无会话限制”的问题

经过一番挣扎和思考,我选择通过创建一个新层作为数据传输来改变我的WebAPI解决方案的体系结构。因此,我只发送等效的DTO(数据传输对象),而不是将实体发送到浏览器

为了在实体和它的DTO等价物之间进行映射,我使用AutoMapper。使用这种方法,当JSON序列化发生时,对象将设置其所有属性,并且不再依赖于NHibernate代理对象

就代码而言,我所做的是:

配置自动映射器:

Mapper.Initialize(cfg => cfg.CreateMap<User, UserDto>());
Mapper.Initialize(cfg => cfg.CreateMap<Role, RoleDto>());
执行以下分析:

IList<RoleDto> dtoList = Mapper.Map<RoleDto>(listOfUsers);
IList dtoList=Mapper.Map(ListoUsers);

就这样。JSON序列化不再带来麻烦。

非常感谢!我做了更多的调试,我意识到问题根本不在于Fluent NHibernate。但是,就像你说的,“懒散的地狱”。这使我遇到了其他问题。他们在这个问题的“更新”中有描述。非常感谢!我做了更多的调试,我意识到问题根本不在于Fluent NHibernate。但是,就像你说的,“懒散的地狱”。这使我遇到了其他问题。在本问题的“更新”中对其进行了描述。