Доступ к динамически создаваемой хранимой процедуре из LINQ - PullRequest
1 голос
/ 06 ноября 2008

Я поворачиваю данные в хранимой процедуре MS SQL. Столбцы, которые поворачиваются, создаются динамически с использованием параметра хранимой процедуры (например, «location1, location2, location3,»), поэтому число генерируемых столбцов неизвестно. Вывод должен выглядеть следующим образом (где местоположения взяты из параметра хранимой процедуры):

OrderTime | Местоположение1 | Location2 | Location3

Есть ли шанс, что это можно использовать в LINQ to SQL? Когда я перетащил эту процедуру в файл dbml, она показывает, что эта процедура возвращает тип int.

Столбцы, которые я использую из таблицы log_sales:

  • Местоположение (различные локации, которые я поворачиваю),
  • Сбор (сумма денег)
  • OrderTime

Хранимая процедура:

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

Ответы [ 3 ]

2 голосов
/ 06 ноября 2008

Предполагая действительно ужасную динамическую потребность, вы можете использовать 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);
0 голосов
/ 06 ноября 2008

Вы запускаете оператор 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)
       })
     });

Вот вторая сводка 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))
     ))
  ));
0 голосов
/ 06 ноября 2008

Вы можете создать свой объект linq для доступа после вашего возвращенного набора данных.

Но будет ли это действительно полезным. Linq полезен для безопасных вызовов, а не для динамических результатов. Вы не знаете, что искать во время компиляции.

...