我想对我的数据做一些报告,比如数据透视表。
我的订单有OrderLines,看起来大致如下:
+----+---------+------------+-----------+-------------+---------+-----------+-----+
| Id | DistrId | ShipDestId | UnitPrice | DateCreated | OrderId | ProductId | Qty |
+----+---------+------------+-----------+-------------+---------+-----------+-----+
| 11 | 221 | 333 | 12.95 | 2015-01-24 | 4 | 12 | 3 |
| 12 | 221 | 333 | 12.95 | 2015-01-24 | 4 | 12 | 9 |
| 16 | 221 | 333 | 12.95 | 2015-01-25 | 5 | 12 | 3 |
| 17 | 221 | 333 | 12.95 | 2015-01-25 | 5 | 12 | 5 |
| 18 | 221 | 333 | 12.95 | 2015-01-25 | 5 | 12 | 2 |
| 19 | 221 | 333 | 14.95 | 2015-01-25 | 5 | 18 | 7 |
+----+---------+------------+-----------+-------------+---------+-----------+-----+
我想使用LINQ生成JSON对象,我简化了Order / OrderLines并将它们分组为Year,Month,Destination,Product,Region(省略)和Division(省略)。因此,我想将其浓缩为3,000个分组行,而不是使用25,000个OrderLines。
目标是将其降低到每月计算的行数,而不是大量的每日订单行。
+------+-------+------+----------+-----------+--------+-----+
| Year | Month | Dest | Dist | Product | Amount | Qty |
+------+-------+------+----------+-----------+--------+-----+
| 2014 | 12 | NY | XYZ, Ltd | Product A | 12.95 | 3 |
| 2015 | 1 | NY | XYZ, Ltd | Product A | 51.8 | 19 |
| 2015 | 1 | NY | XYZ, Ltd | Product B | 14.95 | 7 |
+------+-------+------+----------+-----------+--------+-----+
所以经过LinqPad的大量试验,我想出了这个:
from o in orderLines
group o by new {
o.Order.DateCreated.Year,
o.Order.DateCreated.Month,
Destination = o.Order.ShippingDestination.CompanyName,
Distributor = o.Order.Distributor.CompanyName,
Product = o.Product.ProductName,
Region = o.Order.ShippingDestination.SalesContact.SalesRegion.Name ?? "No Region",
Division = o.Order.ShippingDestination.SalesContact.SalesRegion.SalesDivision.Name ?? "No Division",
Status = o.Order.OrderStatus
} into g
select new {
g.Key.Year,
Month = (g.Key.Month == 1 ? "01 (Jan)" :
g.Key.Month == 2 ? "02 (Feb)" :
g.Key.Month == 3 ? "03 (Mar)" :
g.Key.Month == 4 ? "04 (Apr)" :
g.Key.Month == 5 ? "05 (May)" :
g.Key.Month == 6 ? "06 (Jun)" :
g.Key.Month == 7 ? "07 (Jul)" :
g.Key.Month == 8 ? "08 (Aug)" :
g.Key.Month == 9 ? "09 (Sep)" :
g.Key.Month == 10 ? "10 (Oct)" :
g.Key.Month == 11 ? "11 (Nov)" : "12 (Dec)"),
g.Key.Destination,
g.Key.Distributor,
g.Key.Region,
g.Key.Division,
g.Key.Product,
Cases = g.Sum (x => (Int32?)x.QuantityCases),
Price = g.Sum (x => (Decimal?)x.UnitPrice * x.QuantityCases),
Freight = g.Sum( x => x.Order.Freight ),
g.Key.Status
};
这完全符合我的要求,在我的ASP.NET WEB API和LinqPad中的本地主机上,但当我将我的应用程序部署到服务器时,我等了很长时间,然后我得到:< / p>
"Message":"An error has occurred.","ExceptionMessage":"An error occurred while reading from the
store provider's data reader. See the inner exception for details."
...
"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Timeout expired.
The timeout period elapsed prior to completion of the operation or the server is not responding.",
"ExceptionType":"System.Data.SqlClient.SqlException","StackTrace":" at
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection,
Action`1 wrapCloseInAction)\r\n at
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock,
Boolean asyncClose)\r\n at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,
SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,
TdsParserStateObject stateObj, Boolean& dataReady)\r\n
at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)\r\n
at System.Data.SqlClient.SqlDataReader.Read()\r\n
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.StoreRead()",
"InnerException":{"Message":"An error has occurred.","ExceptionMessage":
"The wait operation timed out","ExceptionType":"System.ComponentModel.Win32Exception","StackTrace":null}}}
当我在LinqPad中执行它时,这是生成的SQL:
SELECT
[Project1].[OrderStatus] AS [OrderStatus],
[Project1].[C3] AS [C1],
CASE WHEN (1 = [Project1].[C4]) THEN N'01 (Jan)' WHEN (2 = [Project1].[C4]) THEN N'02 (Feb)' WHEN (3 = [Project1].[C4]) THEN N'03 (Mar)' WHEN (4 = [Project1].[C4]) THEN N'04 (Apr)' WHEN (5 = [Project1].[C4]) THEN N'05 (May)' WHEN (6 = [Project1].[C4]) THEN N'06 (Jun)' WHEN (7 = [Project1].[C4]) THEN N'07 (Jul)' WHEN (8 = [Project1].[C4]) THEN N'08 (Aug)' WHEN (9 = [Project1].[C4]) THEN N'09 (Sep)' WHEN (10 = [Project1].[C4]) THEN N'10 (Oct)' WHEN (11 = [Project1].[C4]) THEN N'11 (Nov)' ELSE N'12 (Dec)' END AS [C2],
[Project1].[CompanyName] AS [CompanyName],
[Project1].[CompanyName1] AS [CompanyName1],
[Project1].[C5] AS [C3],
[Project1].[C6] AS [C4],
[Project1].[ProductName] AS [ProductName],
[Project1].[C1] AS [C5],
[Project1].[C2] AS [C6],
[Project1].[C7] AS [C7]
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[A2] AS [C2],
[GroupBy1].[K1] AS [OrderStatus],
[GroupBy1].[K2] AS [CompanyName],
[GroupBy1].[K3] AS [CompanyName1],
[GroupBy1].[K4] AS [ProductName],
[GroupBy1].[K5] AS [C3],
[GroupBy1].[K6] AS [C4],
[GroupBy1].[K7] AS [C5],
[GroupBy1].[K8] AS [C6],
(SELECT
SUM([Extent21].[Freight]) AS [A1]
FROM [dbo].[OrderLines] AS [Extent20]
INNER JOIN [dbo].[Orders] AS [Extent21] ON [Extent20].[OrderId] = [Extent21].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent22] ON ([Extent21].[ShippingDestinationId] = [Extent22].[Id]) AND ([Extent22].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent23] ON ([Extent21].[DistributorId] = [Extent23].[Id]) AND ([Extent23].[Discriminator] = N'Distributor')
INNER JOIN [dbo].[Products] AS [Extent24] ON [Extent20].[ProductId] = [Extent24].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent25] ON ([Extent21].[ShippingDestinationId] = [Extent25].[Id]) AND ([Extent25].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent26] ON ([Extent25].[ShippingDestination_SalesContactId] = [Extent26].[Id]) AND ([Extent26].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent27] ON [Extent26].[SalesRegionId] = [Extent27].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent28] ON ([Extent21].[ShippingDestinationId] = [Extent28].[Id]) AND ([Extent28].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent29] ON ([Extent28].[ShippingDestination_SalesContactId] = [Extent29].[Id]) AND ([Extent29].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent30] ON [Extent29].[SalesRegionId] = [Extent30].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent31] ON ([Extent21].[ShippingDestinationId] = [Extent31].[Id]) AND ([Extent31].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent32] ON ([Extent31].[ShippingDestination_SalesContactId] = [Extent32].[Id]) AND ([Extent32].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent33] ON [Extent32].[SalesRegionId] = [Extent33].[Id]
LEFT OUTER JOIN [dbo].[SalesDivisions] AS [Extent34] ON [Extent33].[SalesDivisionId] = [Extent34].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent35] ON ([Extent21].[ShippingDestinationId] = [Extent35].[Id]) AND ([Extent35].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent36] ON ([Extent35].[ShippingDestination_SalesContactId] = [Extent36].[Id]) AND ([Extent36].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent37] ON [Extent36].[SalesRegionId] = [Extent37].[Id]
LEFT OUTER JOIN [dbo].[SalesDivisions] AS [Extent38] ON [Extent37].[SalesDivisionId] = [Extent38].[Id]
WHERE (([GroupBy1].[K5] = (DATEPART (year, [Extent21].[DateCreated]))) OR (([GroupBy1].[K5] IS NULL) AND (DATEPART (year, [Extent21].[DateCreated]) IS NULL))) AND (([GroupBy1].[K6] = (DATEPART (month, [Extent21].[DateCreated]))) OR (([GroupBy1].[K6] IS NULL) AND (DATEPART (month, [Extent21].[DateCreated]) IS NULL))) AND (([GroupBy1].[K2] = [Extent22].[CompanyName]) OR (([GroupBy1].[K2] IS NULL) AND ([Extent22].[CompanyName] IS NULL))) AND (([GroupBy1].[K3] = [Extent23].[CompanyName]) OR (([GroupBy1].[K3] IS NULL) AND ([Extent23].[CompanyName] IS NULL))) AND ([GroupBy1].[K4] = [Extent24].[ProductName]) AND (([GroupBy1].[K7] = (CASE WHEN ([Extent27].[Name] IS NULL) THEN N'No Region' ELSE [Extent30].[Name] END)) OR (([GroupBy1].[K7] IS NULL) AND (CASE WHEN ([Extent27].[Name] IS NULL) THEN N'No Region' ELSE [Extent30].[Name] END IS NULL))) AND (([GroupBy1].[K8] = (CASE WHEN ([Extent34].[Name] IS NULL) THEN N'No Division' ELSE [Extent38].[Name] END)) OR (([GroupBy1].[K8] IS NULL) AND (CASE WHEN ([Extent34].[Name] IS NULL) THEN N'No Division' ELSE [Extent38].[Name] END IS NULL))) AND ([GroupBy1].[K1] = [Extent21].[OrderStatus])) AS [C7]
FROM ( SELECT
[Join18].[K1] AS [K1],
[Join18].[K2] AS [K2],
[Join18].[K3] AS [K3],
[Join18].[K4] AS [K4],
[Join18].[K5] AS [K5],
[Join18].[K6] AS [K6],
[Join18].[K7] AS [K7],
[Join18].[K8] AS [K8],
SUM([Join18].[A1]) AS [A1],
SUM([Join18].[A2]) AS [A2]
FROM ( SELECT
[Extent2].[OrderStatus] AS [K1],
[Extent3].[CompanyName] AS [K2],
[Extent4].[CompanyName] AS [K3],
[Extent5].[ProductName] AS [K4],
DATEPART (year, [Extent2].[DateCreated]) AS [K5],
DATEPART (month, [Extent2].[DateCreated]) AS [K6],
CASE WHEN ([Extent8].[Name] IS NULL) THEN N'No Region' ELSE [Extent11].[Name] END AS [K7],
CASE WHEN ([Extent15].[Name] IS NULL) THEN N'No Division' ELSE [Extent19].[Name] END AS [K8],
[Extent1].[QuantityCases] AS [A1],
[Extent1].[UnitPrice] * CAST( [Extent1].[QuantityCases] AS decimal(19,0)) AS [A2]
FROM [dbo].[OrderLines] AS [Extent1]
INNER JOIN [dbo].[Orders] AS [Extent2] ON [Extent1].[OrderId] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent3] ON ([Extent2].[ShippingDestinationId] = [Extent3].[Id]) AND ([Extent3].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent4] ON ([Extent2].[DistributorId] = [Extent4].[Id]) AND ([Extent4].[Discriminator] = N'Distributor')
INNER JOIN [dbo].[Products] AS [Extent5] ON [Extent1].[ProductId] = [Extent5].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent6] ON ([Extent2].[ShippingDestinationId] = [Extent6].[Id]) AND ([Extent6].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent7] ON ([Extent6].[ShippingDestination_SalesContactId] = [Extent7].[Id]) AND ([Extent7].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent8] ON [Extent7].[SalesRegionId] = [Extent8].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent9] ON ([Extent2].[ShippingDestinationId] = [Extent9].[Id]) AND ([Extent9].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent10] ON ([Extent9].[ShippingDestination_SalesContactId] = [Extent10].[Id]) AND ([Extent10].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent11] ON [Extent10].[SalesRegionId] = [Extent11].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent12] ON ([Extent2].[ShippingDestinationId] = [Extent12].[Id]) AND ([Extent12].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent13] ON ([Extent12].[ShippingDestination_SalesContactId] = [Extent13].[Id]) AND ([Extent13].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent14] ON [Extent13].[SalesRegionId] = [Extent14].[Id]
LEFT OUTER JOIN [dbo].[SalesDivisions] AS [Extent15] ON [Extent14].[SalesDivisionId] = [Extent15].[Id]
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent16] ON ([Extent2].[ShippingDestinationId] = [Extent16].[Id]) AND ([Extent16].[Discriminator] = N'ShippingDestination')
LEFT OUTER JOIN [dbo].[AspNetUsers] AS [Extent17] ON ([Extent16].[ShippingDestination_SalesContactId] = [Extent17].[Id]) AND ([Extent17].[Discriminator] = N'SalesContact')
LEFT OUTER JOIN [dbo].[SalesRegions] AS [Extent18] ON [Extent17].[SalesRegionId] = [Extent18].[Id]
LEFT OUTER JOIN [dbo].[SalesDivisions] AS [Extent19] ON [Extent18].[SalesDivisionId] = [Extent19].[Id]
) AS [Join18]
GROUP BY [K1], [K2], [K3], [K4], [K5], [K6], [K7], [K8]
) AS [GroupBy1]
) AS [Project1]