假设我有一个这样的汇总表:
AcitivityCache
(
pkId (bigint, PK),
Date (DateTime),
OfficeId (int, FK)
TransactionCount (int),
RejectCount (int),
InvitationCount (int),
RequestCount (int)
...
--more counts here--
...
)
现在我需要获取一段时间内的总计数(没有按办公室分组,只是总和),我可以用SQL做这样的事情:
SELECT SUM(TransactionCount) as TotalTxCount, SUM(RejectCount) as TotalRejectCount, ...
FROM ActivityCache
WHERE [Date] between '2011-02-01' and '2012-02-01'
如何使用linq实现这一目标? 到目前为止,我见过的大多数解决方案都有一些分组。但对于这种情况,我不需要分组,只需要总数。我可以这样做:
DateTime dateFrom, toDate; // initialized later
...
var q = dbContext.ActivityCaches
.Where(a=> a.Date > fromDate && a.Date <= toDate)
.GroupBy(a=> 1)
.Select(g=> new
{
TotalTransactionCount = g.Sum(a => a.TransactionCount),
TotalRejectCount = g.Sum(a => a.RejectCount),
...
...
});
或者,我可以先获取列,然后以编程方式获取总和。 或者,我可以使用SP(在这种情况下不喜欢)。 任何更好的想法(没有分组)?
P.S:我无法更改数据库架构
答案 0 :(得分:2)
我不认为LINQ to Entities对这种情况有一些很好的查询。
另一种解决方案是使用Entity SQL (ESQL)
var fromDate = new DateTime(2011, 02, 01);
var toDate = new DateTime(2012, 02, 01);
var esql = @"select
sum(it.TransactionCount) as SumOfTransactionCount,
sum(it.RejectCount) as SumOfRejectCount
from ActivityCaches as it
where it.Date > @fromDate and it.Date <= @toDate";
var query = CreateQuery<DbDataRecord>(esql,
new ObjectParameter("fromDate", fromDate) ,
new ObjectParameter("toDate", toDate));
答案 1 :(得分:1)
另一种方式:
SUM
s 答案 2 :(得分:0)
Linq Aggregate()方法允许在不进行分组的情况下进行求和,如下所示。我担心我没有对数据库进行设置,所以我不保证不会弹出Linq to Sql错误。如果发生这种情况,您可以在执行Aggregate()之前但在where()之后尝试在ActivityCaches()上显示ToList()。
<强>更新强>
我更新了要使用的代码和EF模型。 创建了一个小型EF模型来替换SomeEntry并更新数据以确保我从数据库中读取数据。
private static ActivityLog Aggregate(ActivityLog agg, ActivityLog entry) {
agg.TranCount += entry.TranCount;
agg.ReqCount += entry.ReqCount;
return agg;
}
[TestMethod]
public void AggregateFirstThree() {
var context = new TestDBEntities();
var startDate = new DateTime(2012, 1, 1);
var endDate = new DateTime(2012, 1, 3);
var aggregate = new ActivityLog();
context.ActivityLogs.Where(entry => entry.Timestamp >= startDate && entry.Timestamp <= endDate).Aggregate(aggregate, Aggregate);
Assert.AreEqual(66, aggregate.TranCount);
Assert.AreEqual(36, aggregate.ReqCount);
}
[TestMethod]
public void AggregateLastThree() {
var context = new TestDBEntities();
var startDate = new DateTime(2012, 1, 4);
var endDate = new DateTime(2012, 1, 6);
var aggregate = new ActivityLog();
context.ActivityLogs.Where(entry => entry.Timestamp >= startDate && entry.Timestamp <= endDate).Aggregate(aggregate, Aggregate);
Assert.AreEqual(75, aggregate.TranCount);
Assert.AreEqual(45, aggregate.ReqCount);
}
hth,
艾伦。
答案 3 :(得分:0)
从您的问题中不清楚您想要存储结果的位置。如果您打算将它存储在两个变量中,那么您可以获取数据,使用.Where()扩展方法按日期范围进行过滤,然后使用.Sum()扩展方法来计算总和值。这些方面的东西:
var result = your_query.Where(m => m.Date >= startingDate && m.Date <= endingDate);
var totalTxCount = result.Sum(m => m.TransactionCount);
var totalRejectCount = result.Sum(m => m.RejectCount);