2017-06-22 51 views
2

我正在用.net核心使用web api,angular 2和NHibernate构建一个web应用程序。 我有我的数据库中下表:NHibernate查询json结果是意想不到的

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属性,但类定义呢? 当我从上面的查询创建一个单独的列表时,我得到了我期待在拳头的地方的结果,但这似乎相当麻烦。

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

按照要求,它给我的结果,我希望代码:

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; 
} 

结果返回给客户端用下面的代码:

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

    return new JsonResult(todos); 
} 
+0

哪条线正在生成JSON?你能告诉我们你写的那个工作的替代方案吗? – mjwills

+1

我不认为你已经通过在所得到的query上使用'List()'方法来“实现”你的结果。 –

+0

@David Osborne:我确实很确定这是问题所在,但我不知道如何解决这个问题。 – Bunnynut

回答

1

这可能是一个更合适的方法完成你想要的东西:

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。

我只是想确保我做对了。

当涉及到QueryOver()Query(),没有“正确的方式”。我发现Query()通常更具可读性和整洁,但有时缺乏我可能需要的控制。我通常从Query()开始,如果我卡住了,或者'我不高兴'SQL Query()正在生成,则'升级'到QueryOver()

1
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>()); 

问题的可能原因是您没有将此行代码的结果分配给变量。因为你的query变量转换为JSON而非SelectList调用的结果

[{ 
    "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是可能的。

+0

好的,我可以理解,但我怎么才能正确地做到这一点呢? – Bunnynut

+0

根据下面的文章这是不可能的填充实体属性:http://www.andrewwhitaker.com/blog/2014/06/19/queryover-series-part-4-transforming/ – Bunnynut

+0

“你不能填充完整实体(例如。选择(()=> productReview.Product).WithAlias(()=> result.Product))”在AliasToBean部分 – Bunnynut