NHibernate 查询 json 结果是意外的

NHibernate Query to json results are unexpected

我正在使用 Web api、angular 2 和 NHibernate 使用 .Net Core 构建 Web 应用程序。 我的数据库中有以下表格:

待办事项

ID
Name
Priority

优先级

ID
Name

以及这些表的以下映射:

[Class(NameType = typeof(Todo), Table = "Todo")]
public class Todo
{
    [ID(-2, Name = "ID")]
    [Generator(-1, Class = "native")]
    public virtual long ID { get; set; }

    [Property]
    public virtual string Name { get; set; }

    [ManyToOne]
    public virtual Priority Priority { get; set; }
}

[Class (NameType = typeof(Priority), Table = "Priority")]
public class Priority
{
    [ID(-2, Name = "ID")]
    [Generator(-1, Class = "native")]
    public virtual long ID { get; set; }

    [Property]
    public virtual string Name { get; set; }
}

我还有以下 DTO,我想创建一个列表并将其发送给 json 中的客户端: 出于本示例的目的,我从中删除了一些其他属性。

public class TodoDTO
{
    public long ID { get; set; }

    public string Name { get; set; }

    public Priority Priority { get; set; }
}

当我运行下面的查询时:

var session = SessionFactoryConfigurationBase.GetSessionFactory().GetCurrentSession();

var query = session.QueryOver<Todo>();

TodoDTO todoSummary = null;

query.SelectList(list => list
    .Select(t => t.ID).WithAlias(() => todoSummary.ID)
    .Select(t => t.Name).WithAlias(() => todoSummary.Name)
    .Select(t => t.Priority).WithAlias(() => todoSummary.Priority))
.TransformUsing(Transformers.AliasToBean<TodoDTO>());

生成的 json 不显示 PriorityIDName 属性,但显示以下内容:

[{
    "id":1,
    "name":"TEST",
    "priority":
    {
        "__interceptor":
        {
            "persistentClass":"Todo, ApplicationName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "identifier":2,
            "isUninitialized":true,
            "unwrap":false,
            "session":null,
            "entityName": "Priority",
            "isReadOnlySettingAvailable":false
        }
    }
}]

为什么它不显示 IDName 属性而是显示 class 定义? 当我从上面的查询创建一个单独的列表时,我在第一个地方得到了我期望的结果,但这看起来很麻烦。

--------------------编辑-------------------- --

按照要求,确实给我预期结果的代码:

public IList<Todo> GetTodos()
{
        var session = SessionFactoryConfigurationBase.GetSessionFactory().GetCurrentSession();

    var query = session.QueryOver<Todo>()
    .Fetch(t => t.Priority).Eager
    .List<Todo>();

    if(!query.Any())
    {
        return null;
    }

    var result = (
        from t in query
        select new TodoDTO
        {
            ID = t.ID,
            Name = t.Name,
            Priority = t.Priority
        }
    ).ToList();        

    return result;
}

结果是return给客户端,代码如下:

public JsonResult GetTodos()
{
    var todos = GetTodos();

    return new JsonResult(todos);
}

这可能是实现您想要的更简洁的方法:

var todos = 
    session
        .Query<Todo>()
        .Fetch(t => t.Priority)
        .Select(t => 
            new {
               t.ID,
               t.Name,
               Priority = new {
                   t.Priority.Id,
                   t.Prioriry.Name}
            })
        .ToList();

return new JsonResult(todos);

我省略了 DTO 以证明它不是绝对必要的。但是,可以更改 Select() 调用以创建新的 DTO。

I just want to make sure that I'm doing it right.

说到QueryOver()Query(),就没有'right way'了。我发现 Query() 通常更具可读性和整洁性,但有时缺乏我可能需要的控制。我通常从 Query() 和 'escalate' 开始到 QueryOver() 如果我卡住了或者我不高兴 SQL Query() 正在生成。

query.SelectList(list => list
    .Select(t => t.ID).WithAlias(() => todoSummary.ID)
    .Select(t => t.Name).WithAlias(() => todoSummary.Name)
    .Select(t => t.Priority).WithAlias(() => todoSummary.Priority))
.TransformUsing(Transformers.AliasToBean<TodoDTO>());

您的问题的可能原因是您没有将这行代码的结果分配给变量。

[{
    "id":1,
    "name":"TEST",
    "priority":
    {
        "__interceptor":
        {
            "persistentClass":"Todo, ApplicationName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "identifier":2,
            "isUninitialized":true,
            "unwrap":false,
            "session":null,
            "entityName": "Priority",
            "isReadOnlySettingAvailable":false
        }
    }
}]

您收到的上述 JSON 可能是因为您正在将 query 变量转换为 JSON 而不是 [=13= 的结果] 呼叫.