1

我在 MS SQL 存储过程中旋转数据。旋转的列是使用存储过程参数(例如:“location1,location2,location3”)动态创建的,因此将生成的列数是未知的。输出应如下所示(位置取自存储过程参数):

订购时间 | 位置1 | 位置2 | 位置3

这有可能在 LINQ to 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

在 dbmldesigner.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));
}
4

3 回答 3

2

假设真正可怕的动态需求,您可以使用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);
于 2008-11-05T22:13:30.703 回答
0

您可以在返回数据集后创建 linq 对象以供访问。

但这真的有用吗。Linq 对于类型安全调用而不是动态结果很有用。您将不知道要查找什么编译时间。

于 2008-11-05T21:40:56.930 回答
0

你会运行你的选择语句

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

这是第二个关键的 Linq,它将数据推送到 XML 而不是匿名类型。

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))
     ))
  ));
于 2008-11-05T21:52:43.707 回答