警告:我知道这些代码的某些部分很糟糕,但它现在就是这样。我只是想让它正常运行。我完全打算稍后重构。我现在只需要一个正常工作的应用程序。
初始linq查询会抓取几个数据字段,但必须在结果集中的每个项目中添加更多数据。所以,我们有下面的foreach。它抓取数据并更新每一行。
它覆盖了我所想的一切,可能是foreach的最后一次迭代。为什么?如何防止覆盖?
请记住,工作变量只是一个句点ID。我想获得前一个或未来的时期,减去或添加到这个允许这个。
public List<intranetGS.Forecast> getForecast(int branchId) {
//user role protection here
intraDataContext q = new intraDataContext();
//this grabs the initial data
var basefc = (from f in q.fc_items
where f.color_option == false
select new intranetGS.Forecast {
itemId = f.item_id,
item = f.item_number,
itemDesc = f.description,
itemSuffix = f.item_suffix,
itemPrefix = f.item_prefix,
designation = f.designation
});
//now we filter
switch (getDesignation(branchId)) {
case 1:
basefc = basefc.Where(n => n.designation != 3);
basefc = basefc.Where(n => n.designation != 6);
break;
case 2:
basefc = basefc.Where(n => n.designation > 3);
break;
case 3:
basefc = basefc.Where(n => n.designation != 2);
basefc = basefc.Where(n => n.designation != 6);
break;
}
var current = Convert.ToInt32(DateTime.Now.Month);
var working = 0;
var year = Convert.ToInt32(DateTime.Now.Year);
List<intranetGS.Forecast> res = new List<intranetGS.Forecast>();
foreach (var f in basefc) {
working = getPeriod(current + "/" + (year - 1)); //starting with last year;
var ly = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(ly, null)) {
f.lastYearForecast = ly.forecast;
f.lastYearReceipt = ly.receipt;
}
working = getPeriod(current + "/" + year) - 2; //two months ago
var m2 = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(m2, null)) {
f.twoMosForecast = m2.forecast;
f.twoMosReceipts = m2.receipt;
f.twoMosUsage = m2.usage_lb;
}
working = getPeriod(current + "/" + year) - 1; //one month ago
var m1 = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(m1, null)) {
f.oneMosForecast = m1.forecast;
f.oneMosReceipts = m1.receipt;
f.oneMosUsage = m1.usage_lb;
}
working = getPeriod(current + "/" + year); //current month
var m = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(m, null)) {
f.currentMosForecast = m.forecast;
f.currentMosReceipts = m.receipt;
f.currentMosusage = m.usage_lb;
}
working = getPeriod(current + "/" + year) + 1; //one month from now
var mnext1 = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(mnext1, null)) {
f.plusOneForecast = mnext1.forecast;
f.plusOneForecastId = mnext1.forcast_id;
}
working = getPeriod(current + "/" + year) + 2; //two months from now
var mnext2 = (from l in q.fc_forecasts where l.period == working && l.branch == branchId && l.item == f.itemId select l).FirstOrDefault();
if (!object.ReferenceEquals(mnext2, null)) {
f.plusTwoForecast = mnext2.forecast;
f.plusTwoForecastId = mnext2.forcast_id;
}
} //this is insanely and extremely cumbersome; refactor later.
return basefc;
}
更新:它不是一个列表,它需要是一个列表以避免覆盖。
答案 0 :(得分:1)
问题是,当用户构建查询时,linq中会发生延迟执行,并且在内部构建一个可以添加新表达式的表达式树。在执行期间确定查询因子后,例如for循环中的可枚举目标或通过.ToList()
该列表仍然是 fluid 。由于代码只是添加更多表达式而不是将其过滤到新列表中,因此查询增长了。
问题是在处理现有代码时,开发人员是否希望继续构建表达式树以获得性能,或者他们是否打算在流程的每个步骤中创建项目具体?
您可能会通过使初始列表具体化来修复问题,但可能会在未来引入逻辑错误。记住这一点。