将4.5.1与服务器端的应用程序一起使用,同时将图表数据与许多REST请求混合。
使用IQueryable构建查询。例如,我最初具有以下内容:
var query = ctx.Respondents
.Join(
ctx.Respondents,
other => other.RespondentId,
res => res.RespondentId,
(other, res) => new ChartJoin { Respondent = res, Occasion = null, BrandVisited = null, BrandInfo = null, Party = null, Item = null }
)
. // bunch of other joins filling out the ChartJoin
.Where(x => x.Respondent.status == 1)
. // more Where clauses dynamically applied
.GroupBy(x => new CommonGroupBy { Year = (int)x.Respondent.currentVisitYear, Month = (int)x.Respondent.currentVisitMonth })
.OrderBy(x => x.Key.Year)
.ThenBy(x => x.Key.Month)
.Select(x => new AverageEaterCheque
{
Year = x.Key.Year,
Month = x.Key.Month,
AverageCheque = (double)(x.Sum(m => m.BrandVisited.DOLLAR_TOTAL) / x.Sum(m => m.BrandVisited.NUM_PAID)),
Base = x.Count(),
Days = x.Select(m => m.Respondent.visitDate).Distinct().Count()
});
为了允许动态分组(通过客户端),GroupBy是使用返回Dictionary的C#表达式生成的。 Select也必须使用表达式生成。上面的Select变成了:
public static Expression<Func<IGrouping<IDictionary<string, object>, ChartJoin>, AverageEaterCheque>> GetAverageEaterChequeSelector()
{
// x =>
var ParameterType = typeof(IGrouping<IDictionary<string, object>, ChartJoin>);
var parameter = Expression.Parameter(ParameterType);
// x => x.Sum(m => m.BrandVisited.DOLLAR_TOTAL) / x.Sum(m => m.BrandVisited.NUM_PAID)
var m = Expression.Parameter(typeof(ChartJoin), "m");
var mBrandVisited = Expression.PropertyOrField(m, "BrandVisited");
PropertyInfo DollarTotalPropertyInfo = typeof(BrandVisited).GetProperty("DOLLAR_TOTAL");
PropertyInfo NumPaidPropertyInfo = typeof(BrandVisited).GetProperty("NUM_PAID");
....
return a lambda...
}
当我在本地进行测试运行时,出现Out of Memory错误。然后我开始阅读Totin和Lambda编译的其他人的博客,表达树一般都很昂贵。不知道它会破坏我的申请。我需要能够动态添加分组,这导致我使用表达式树作为GroupBy和Select子句。
是否会喜欢关于如何在应用程序中追踪内存违规者的一些指示?已经看到有些人使用dotMemory,但也有一些实用技巧。监控C#,DotNet的经验很少。
答案 0 :(得分:4)
由于您正在将表达式编译为委托,因此使用LINQ to Objects执行操作,而不是使用IQueryable
重载。这意味着整个数据集被拉入内存,并且所有处理都由应用程序完成,而不是在数据库中完成,只有最终结果被发送到应用程序。
显然将整个表格拉入内存就足以让你的应用程序无法运行。
您需要不编译lambda,并将其保留为表达式,从而允许查询提供程序将其转换为SQL,就像使用原始代码一样。