문제

MS SQL 저장 프로 시저에서 데이터를 피봇하고 있습니다. 피벗 된 열은 저장된 프로 시저 매개 변수 (exampe : "location1, location2, location3,")를 사용하여 동적으로 생성되므로 생성 될 열의 수는 알려져 있지 않습니다. 출력은 (위치가 저장 프로 시저 매개 변수에서 가져온 위치)

OrderTime | 위치 1 | 위치 2 | 위치 3

LINQ에서 SQL에서 사용할 수 있습니까? 이 절차를 DBML 파일로 드래그하면이 프로 시저가 int 유형을 반환 함을 보여줍니다.

내가 사용하는 열 log_sales 테이블은 다음과 같습니다.

  • 위치 (내가 피벗하는 다양한 위치),
  • 청구 (금액)
  • 주문 시간

저장 절차 :

CREATE PROCEDURE [dbo].[proc_StatsDay] @columns NVARCHAR(64) AS

DECLARE @SQL_PVT1 NVARCHAR(512), @SQL_PVT2 NVARCHAR(512), @SQL_FULL NVARCHAR(4000);

SET @SQL_PVT1 =  'SELECT OrderTime, ' + LEFT(@columns,LEN(@columns)-1) +'
FROM (SELECT ES.Location, CONVERT(varchar(10), ES.OrderTime, 120),ES.Charge
        FROM dbo.log_sales ES
        ) AS D (Location,OrderTime,Charge)
        PIVOT (SUM (D.Charge) FOR D.Location IN
            (';
SET @SQL_PVT2 = ') )AS PVT
ORDER BY OrderTime DESC';

SET @SQL_FULL = @SQL_PVT1 + LEFT(@columns,LEN(@columns)-1) + 
@SQL_PVT2;       

EXEC sp_executesql @SQL_FULL, N'@columns NVARCHAR(64)',@columns = @columns

DBML에서 designer.cs 저장된 프로 시저를 코드의 파일 :

[Function(Name="dbo.proc_StatsDay")]
public int proc_EasyDay([Parameter(DbType="NVarChar(64)")] string columns)
{
    IExecuteResult result = this.ExecuteMethodCall(this,((MethodInfo)MethodInfo.GetCurrentMethod())), columns);
    return ((int)(result.ReturnValue));
}
도움이 되었습니까?

해결책

진정으로 무서운 역동적 인 요구를 가정하면 사용할 수 있습니다 DataContext.ExecuteQuery

결과 공간을 포괄하는 유형을 채찍 올리십시오 (속성 이름은 쿼리의 열 이름과 일치해야합니다).

public class DynamicResult
{
  public DateTime OrderDate {get;set;}
  public decimal? Location1 {get;set;}
  public decimal? Location2 {get;set;}
//..
  public decimal? Location100 {get;set;}
}

그런 다음 전화하십시오

IEnumerable<DynamicResult> result =
  myDataContext.ExecuteQuery<DynamicResult>(commandString, param1);

다른 팁

반환 된 데이터 세트 후에 액세스 할 수있는 LINQ 객체를 만들 수 있습니다.

그러나 그것은 실제로 어떤 용도로든 될 것입니다. LINQ는 TypeSAFE 호출에 유용하며 동적 결과가 아닙니다. 컴파일 시간을 찾아야 할 사항을 모를 것입니다.

Select 문을 실행합니다

SELECT ES.Location, DateAdd(dd, DateDiff(dd, 0, ES.OrderTime), 0),ES.Charge
FROM dbo.log_sales ES

결과를 이와 같은 유형으로 캡처하십시오

public class LogSale
{
  public string Location {get;set;}
  public DateTime OrderDate {get;set;}
  public decimal Charge {get;set;}
}

그런 다음 "피벗"/메모리에서 정리하십시오.

List<LogSale> source = LoadData();
var pivot = source
  .GroupBy(ls => ls.OrderDate)
  .OrderBy(g => g.Key)
  .Select(g => new {
     Date = g.Key,
     Details = g
       .GroupBy(ls => ls.Location)
       .Select(loc => new {
          Location = loc.Key,
          Amount = loc.Sum(ls => ls.Charge)
       })
     });

다음은 익명 유형 대신 데이터를 XML로 푸시하는 두 번째 Pivoty LINQ입니다.

var pivot = source
  .GroupBy(ls => ls.OrderDate)
  .OrderBy(g => g.Key)
  .Select(g => new XElement("Date",
    new XAttribute("Value", g.key),
    g.GroupBy(ls => ls.Location)
     .Select(loc => new XElement("Detail",
       new XAttribute("Location", loc.Key),
       new XAttribute("Amount", loc.Sum(ls => ls.Charge))
     ))
  ));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top