2017-02-17 5 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

우리는 다른 접근 방식을 시도했지만 아무 것도 효과가 없었습니다. 하나의 쿼리로 원하는 결과를 얻을 수 있습니까?

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

원래 우리는 원료에 해당하는 각각의 전체 주식을 보여 그리드를했다 :

나는이 모델이있다.

Current Stocks Total

을 그리고 위에서 언급 한 바와 같이 지금, 우리는 목록을 보여 드리고자합니다 :

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

이 데이터는 다음과 유사한 표에 나와 있습니다 : 우리는이 쿼리 정보를 검색 상기 구성 요소를 제공 한 공급자. 하나의 쿼리로 모든 것을 수행 할 수 있습니까?

Desired table

+0

최대 절전 모드 솔루션을 찾고 계십니까? SQL Server 솔루션? 내가 최대 절전 모드로 당신을 도울 수 없지만 SQL 서버에서 물건을 사용할 수 있고 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이 누락되어 표시하지 않은 내용을 복제하지 않고 단순한 목적으로 제 답변에서 해당 내용을 제거했습니다. 어쨌든, 나는 그것이 ID와 이름을 표시는하지만 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, NAME = Sup1), (식 3 NAME = Sup3)

2 NAME2 20.00 (ID = 1, NAME = Sup1) .. .

나는 여전히 당신의 요구 사항을 충족 생각

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

를, 그리고 목록이 그룹에 노력 피한다 : (210)

+0

예, StockType을 추가하는 것을 잊었지만 실제로는 그 질문과 관련이 없습니다. 또한 Nhibernate를 사용하고 있습니까? 아니면 완전히 메모리 테스트 중입니까? – Dzyann

+0

이것은 메모리에 있지만 데이터 모델이 맞는지는 중요하지 않습니다. LINQ는 데이터 소스를 추상화 한 것으로, 메모리, SQL, no-SQL 등 여부에 관계없이 데이터를 조작 할 수 있습니다. – bc004346

+0

Linq To SQL이 SQL로 변환되고 Nhibernate를 얻으므로 문제가됩니다. 예외. Linq을 작성하여 SQL에서 쿼리를 가장 적게 생성합니다. – Dzyann

1

당신은 시도 할 수 있습니다. 하지만 NHibernate에 의해 실행될 수 있는지 확실하지 않습니다.

그룹을 피함으로써 더 쉽게 할 수 있습니다. RawMaterial을 검색어의 루트로 사용하는 이유는 무엇입니까?이 경우 RawMaterialStocks 컬렉션을 추가해야합니다 (또는 하위 쿼리 사용). 내가 쿼리의이 종류는 EF에 의해 처리됩니다 알고,하지만 난 NHibernate에와 같은 쿼리를 시도하지 않은

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

:

추측 this.RawMaterials는 뭔가 같은 것, 존재하고 IQueryable<RawMaterial>입니다. (NHibernate는 Iz가 가능하다면 lazy-loading batching 덕분에 children 콜렉션을로드하는 것이 훨씬 낫다.) 그래서 나는 Hibernate를 사용하려고하지 않는다.)