2017-02-17 7 views
1

グループの複合キーの一部として要素のリストを取得したいと考えています。しかし、これまで私はそれを行うためのクエリを書くことができませんでした。LinqのキーへのリストをSqlグループに追加する方法

RawMaterialあたりの合計在庫を表示しています(モデルの詳細はこちら)。RawMaterialのサプライヤーと一緒にリストしたいと思います。 私はこのクエリを試してみました:

var list = this.Stocks.Where(x => x.StockType == StockTypeEnum.RawMaterialEntered) 
.GroupBy(i => new { RawMaterialId = i.RawMaterial.Id, RawMaterial = i.RawMaterial.Name, 
        Suppliers = i.RawMaterial.Suppliers.Select(j=> new { Id= j.Supplier.Id, Name = j.Supplier.Name}) }) 
.Select(g => new StockSummary 
{ 
    TotalAmount = g.Sum(i => i.Amount), 
    ComponentId = g.Key.RawMaterialId,     
    Component = g.Key.RawMaterial, 
    Suppliers = g.Key.Suppliers.Select(h=> new StockItemModel(){ Id = h.Id, Name = h.Name}).ToList() 
}) 
.OrderByDescending(g => g.Component).ToList(); 

それはビルドするが、私はそれを実行しようとすると、私はこの例外を取得:

型「System.NotImplementedException」 の最初のチャンス例外がNHibernateの中で起こりました。 dll

私たちはさまざまなアプローチを試みましたが、何も機能しませんでした。 1つのクエリで目的の結果を得ることは可能ですか?

public class Stock 
{ 
    public RawMaterial RawMaterial{ get; set; } 
    public int Amount { get; set; } 
} 

public class RawMaterial 
{ 
    public int Id{ get;set; } 
    public string Name { get;set; } 
    public IList<SupplierInfo> SupplierInfos{ get;set; } 
} 

public class SupplierInfo 
{ 
    public int Id{ get;set; } 
    public Supplier Supplier { get;set; } 
} 

public class Supplier 
{ 
    public int Id { get;set; } 
    public string Name { get; set; } 
} 

はもともと我々は原料に利用可能な各総株式を表示するグリッドを持っていた:

私はこのモデルを持っています。私たちは、このクエリでその情報を取得する:

var list = this.Stocks.Where(x => x.StockType == StockTypeEnum.RawMaterialEntered) 
    .GroupBy(i => new { RawMaterialId = i.RawMaterial.Id, RawMaterial = i.RawMaterial.Name }) 
    .Select(g => new StockSummary 
       { 
        TotalAmount = g.Sum(i => i.Amount), 
        ComponentId = g.Key.RawMaterialId,     
        Component = g.Key.RawMaterial,     
       }) 
       .OrderByDescending(g => g.Component).ToList(); 

このデータは、このような表に示されている:

Current Stocks Total

そして、前述したように、今、私たちはのリストを表示したいと思い前記コンポーネントを提供したサプライヤ。 1つのクエリですべてを行うことは可能ですか?すべての

Desired table

+0

ハイバネートソリューションSQL Serverのソリューションですか?私は休止状態であなたを助け始めることができませんでしたが、SQL Serverでこれを簡単にXMLを使用することができます。ここを見てください。 http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005 –

+0

'GroupBy'コールのリストでデータをグループ化していますか?私が知る限り、NHibernateもEFもそのような操作をサポートしていません。 –

+0

いいえ、あなたは1つのクエリでそれを行うことはできません。最初のクエリで必要なすべての結果を取得し、すべてをデータベースからロードし、アプリケーションでグループ化します。私はあなたがしたいことがSQLで可能であるかどうかはわかりません。 – Sidewinder94

答えて

0

したがって、最初の、あなたのコードが不完全であるか、あなたはここにすべてのものを貼り付けていませんでした。たとえばStockTypeStockEnumTypeがありません。わたしはあなたが示していないものを複製しようとするのではなく、単純な目的のために答えから削除しました。とにかく、私はstring.Join(",", ...)を使用している場合、それはIDと名前を表示していますが、それは私のために正常に動作しますが、私はあなたが何の問題あなたのLINQステートメントを変更することで出力を調整持たないべきではないと思う:

 var list = stocks 
      .GroupBy(i => new { RawMaterialId = i.RawMaterial.Id, RawMaterial = i.RawMaterial.Name, 
       Suppliers = i.RawMaterial.SupplierInfos.Select(j => new { Id = j.Supplier.Id, Name = j.Supplier.Name }) 
      }) 
      .Select(g => new 
      { 
       TotalAmount = g.Sum(i => i.Amount), 
       ComponentId = g.Key.RawMaterialId, 
       Component = g.Key.RawMaterial, 
       Suppliers = string.Join(",", g.Key.Suppliers.Select(h => new { Id = h.Id, Name = h.Name }).ToList()) 
      }) 
      .OrderByDescending(g => g.Component).ToList(); 

をし、出力は私であります試験データ:

1 NAME3 30.00(ID = 1、名前= SUP1)、(ID = 3、NAME = Sup3を搭載)

2 Name2は20.00(ID = 1、名前= SUP1) .. 。

+0

はい、StockTypeを追加するのを忘れましたが、実際にはその質問には関係ありません。また、Nhibernateを使用していますか?または、完全に記憶テストですか? – Dzyann

+0

これはメモリ内ですが、データモデルが正しいかどうかは関係ありません。 LINQは、メモリ内、SQL、no-SQLなどのデータに関係なく、データソースを抽象化したものです。 – bc004346

+0

Linq To SQLがSQLに変換され、Nhibernate例外。 Linqを書いて、SQLで最小限のクエリしか生成しないようにしたい。 – Dzyann

1

あなたは試みることがあります。

var list = this.Stocks 
    .Where(x => x.StockType == StockTypeEnum.RawMaterialEntered) 
    .GroupBy(i => 
     new 
     { 
      RawMaterialId = i.RawMaterial.Id, 
      RawMaterial = i.RawMaterial.Name 
     }) 
    .Select(g => new StockSummary 
    { 
     TotalAmount = g.Sum(i => i.Amount), 
     ComponentId = g.Key.RawMaterialId,     
     Component = g.Key.RawMaterial, 
     Suppliers = g 
      .SelectMany(s => 
       s.RawMaterial.SupplierInfos.Select(j => 
        new { Id = j.Supplier.Id, Name = j.Supplier.Name })) 
      .Distinct() 
      .Select(h => new StockItemModel() { Id = h.Id, Name = h.Name }) 
      .ToList() 
    }) 
    .OrderByDescending(g => g.Component).ToList(); 

を、私はそれはまだあなたの条件にマッチすると思うし、それがリストでグループにしようとして回避します。しかし、私はそれがNHibernateで実行できるかどうかはわかりません。

グループを回避すると、クエリのルートとしてRawMaterialを使用しないのはなぜですか?これには、RawMaterialStocksコレクションを追加する(またはサブクエリを使用する)必要があります。 this.RawMaterialsを推測

IQueryable<RawMaterial>が存在すると、それはようなものになるだろう:私は、クエリのこの種を知っている

var list = this.RawMaterials 
    .Where(rm => 
     rm.Stocks.Any(s => s.StockType == StockTypeEnum.RawMaterialEntered)) 
    .Select(rm => new StockSummary 
    { 
     TotalAmount = rm.Stocks 
      .Where(s => s.StockType == StockTypeEnum.RawMaterialEntered) 
      .Sum(s => s.Amount), 
     ComponentId = rm.Id,     
     Component = rm.Name, 
     Suppliers = rm.SupplierInfos 
      .Select(si => 
       new StockItemModel() 
       { 
        Id = si.Supplier.Id, 
        Name = si.Supplier.Name 
       }) 
      .ToList() 
    }) 
    .OrderByDescending(ss => ss.Component).ToList(); 

EFによって処理されますが、私はNHibernateはこのようなクエリを試していません。 (NHibernateは、レイジーローディングバッチ処理(有効になっている場合)のおかげで、EFよりも子コレクションをロードするほうがはるかに優れているため、NHibernateでは使用しようとしているプロジェクションを使用しません)。

関連する問題