2017-06-22 5 views
2

私はwebアプリケーションを構築しています.Net Coreはweb api、angular 2とNHibernateを使用しています。 私は、データベース内の次のテーブルがあります。私はまた、次のを持っているNHibernate json結果へのクエリが予期しないです

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

藤堂

ID 
Name 
Priority 

優先

ID 
Name 

そして、これらのテーブルの次のマッピングを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というプロパティが表示されますが、代わりにクラス定義が表示されますか? 上記のクエリとは別のリストを作成すると、私が最初の場所で期待した結果が得られますが、それはやや面倒です。

--------------------- EDIT ------------------------

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

    return new JsonResult(todos); 
} 
+0

JSONを生成しているのは、どのラインですか?あなたが書いた代替案を見せてもらえますか? – mjwills

+1

結果の 'query'メソッドで' List() 'メソッドを使って結果を '実現した'とは思いません。 –

+0

@David Osborne:私は実際にそれが問題だと確信していますが、私はそれを正確に修正する方法を知らない。 – Bunnynut

答えて

1

これはおそらく、滑らかな印象の方法です:

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

結果は次のコードでクライアントに返すです: -

としては、私が期待する結果が得られないコードを要求しましたあなたが望むものを達成するために:

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

このコード行の結果を変数に代入していない可能性があります。あなたがSelectList呼び出しの結果ではなく、JSONにquery変数を変換しているので、あなたが受けている

[{ 
    "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

"完全なエンティティ(例:.Select(()=> productReview.Product).WithAlias(()=> result.Product)) "AliasToBeanセクションの最後の段落の段落内 – Bunnynut