2017-02-17 64 views
1

我想檢索作爲組的組合鍵的一部分的元素列表。但到目前爲止,我一直無法編寫查詢來完成它。如何將列表添加到Linq to 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

我們嘗試了不同的方法,但沒有奏效。只用一個查詢就可以獲得想要的結果嗎?

我有這樣的模式:

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

而現在,如上文提到的,我們想展現的列表提供所述組件的供應商。是否可以在一個查詢中完成所有操作?

Desired table

+0

你正在尋找一個休眠解決方案或一個SQL Server解決方案?我無法開始幫助您使用hibernate,但在sql server中,您可以輕鬆使用這些東西和xml。看看這裏。 http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005 –

+0

你是否在GroupBy調用中按列表分組數據?據我所知,NHibernate和EF都不支持這種操作。 –

+0

我會說不,你不能在一個查詢中做到這一點。獲得第一個查詢所需的所有結果,將它們全部從數據庫加載並將它們分組到應用程序中。我不確定你想要做什麼甚至可能在SQL中。 – Sidewinder94

回答

0

所以首先,你的代碼是不完整的,或者你做的一切都是在這裏不糊。例如StockTypeStockEnumType已丟失,爲了簡單起見,我將其從答案中刪除,而不是嘗試複製您未顯示的內容。不管怎麼說,它工作正常,我如果我使用string.Join(",", ...)雖然它出示身份證和姓名,但我認爲你不應該沒有問題,通過修改你的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,名稱= SUP3)

2名稱2 20.00(ID = 1,名稱= SUP1) .. 。

+0

是的,我忘了添加StockType,但這些與問題無關。你也使用Nhibernate?或者完全是內存測試? – Dzyann

+0

這是內存中的,但如果您的數據模型是正確的,則無關緊要。 LINQ是對數據源的一種抽象,它允許您操縱數據,而不管它是否在內存中,SQL,無SQL等。 – bc004346

+0

它確實很重要,因爲Linq To SQL被轉換爲SQL,並且我得到了一個N​​hibernate例外。我想編寫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作爲查詢的根?這需要在RawMaterial(或使用子查詢)上添加Stocks集合。

猜測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的那種投影你試圖。)

相關問題