Простая проблема (РЕДАКТИРОВАНИЕ: сначала показать легко воспроизводимый пример, а затем подробный сценарий)
Имея следующие классы:
public class SalesMetrics {
public decimal SalesDollars { get; set; }
public decimal SalesUnits { get; set; }
}
public class ProductGroup {
public string ProductId { get; set; }
public string ProductName { get; set; }
}
с использованием следующего DapperЗапрос, мой результат равен [{Key = null, Value = null}]
:
IEnumerable<KeyValuePair<ProductGroup, SalesMetrics>> result = sqlConnection
.Query<KeyValuePair<ProductGroup, SalesMetrics>>(
sql: @"SELECT
1 As ProductId,
'Test' AS ProductName,
1.00 As SalesDollars,
1 As SalesUnits");
Мне интересно, может ли Dapper обрабатывать KeyValuePair как тип вывода, так: как должен быть запрос?
Полный сценарий (Зачем мне это нужно)
Я создаю функцию построителя Sales Query, которая может группировать мои результаты продаж по разным предикатам группировки и должна возвращать другой тип результата на основе этогоПредикат type
.
Я использую пакет Dapper
nuget для получения результата от SQL-Server
. Я использую Dapper.Query<T>()
метод расширения для IDbConnection
В принципе, независимо от группировкиТип Я хочу вернуть sum
SalesDollars & SalesUnits. Для этой части вывода я создал следующий класс SalesMetrics
Я хочу, чтобы моя функция Sales Query принимала класс Group (ProductGroup
или любой другой класс ...) как generic parameter
named TGroup
, функция должна возвращать коллекцию KeyValuePair<TGroup,SalesMetric>
источник данных
Вот схема моей таблицы продаж FlatSales
CREATE TABLE dbo.FlatSales (
SalesDate DATE NOT NULL,
ProductId INT NOT NULL,
ProductName VARCHAR(100) NOT NULL,
ProductCategoryId INT NOT NULL,
ProductCategoryName VARCHAR(100) NOT NULL,
CustomerGroupId INT NOT NULL,
CustomerGroupName VARCHAR(100) NOT NULL,
CustomerId INT NOT NULL,
CustomerName VARCHAR(100) NOT NULL,
SalesUnits INT NOT NULL,
SalesDollars INT NOT NULL
)
Там, где у меня проблема
У меня есть следующая функция для запросов к БД.
public static IEnumerable<KeyValuePair<TGroup,SalesMetrics>> SalesTotalsCompute<TGroup>(System.Data.IDbConnection connection)
{
string[] groupByColumnNames = typeof(TGroup)
.GetProperties(bindingAttr: System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
.Select(x => x.Name)
.ToArray();
string joinedGroupByColumnsNames = string.Join(",", groupByColumnNames);
return connection.Query<KeyValuePair<TGroup, SalesMetrics>>(sql: $@"
SELECT SUM(SalesDollars) AS SalesDollars,
SUM(SalesUnits) AS SalesUnits,
{joinedGroupByColumnsNames}
FROM dbo.FlatSales
GROUP BY {joinedGroupByColumnsNames}
");
}
Коллекция NULL
Код does not fail
, но он возвращает список KeyValuePair, в котором ключ и значение имеют значение NULL
.
Я пытался присвоить псевдонимы моим столбцам, например ProductName as [Key.ProductName]
, нотогда это ничего не меняет (также не сбоит) ...
Сгенерированные запросы Sql для ProductGroup
выглядят следующим образом (оба возвращают пустой KeyValuePair):
SELECT SUM(SalesDollars) AS SalesDollars,
SUM(SalesUnits) AS SalesUnits,
ProductId,ProductName
FROM dbo.FlatSales
GROUP BY ProductId,ProductName
OR
SELECT SUM(SalesDollars) AS SalesDollars as [Value.SalesDollars],
SUM(SalesUnits) AS SalesUnits as [Value.SalesUnits],
ProductId As [Key.ProductId],ProductName As [Key.ProductName]
FROM dbo.FlatSales
GROUP BY ProductId,ProductName
Есть идеи?