我在ASP.NET MVC应用程序中遇到了一些性能问题。我有一个列表,我需要设置几个属性。我的代码通过for循环读取列表,并根据记录日期值设置这两个属性。
以下是代码:
//Build City Taxes List
var cityTaxInformationList = (from citycigtax ct in db.citycigtaxes
join statecigtax st in db.statecigtaxes on ct.stateid equals st.stateid
join transaction tr in db.transactions on ct.masterkey equals tr.masterkey
select new CityViewModel
{
CityMasterKey = ct.masterkey,
StateShortName = st.stateshortname,
CityName = ct.cityname,
TransactionStickTax = tr.sticktax,
TransactionDateStamp = tr.datestamp,
TransactionEffectiveDate = tr.effdate,
TransactionKey = tr.transactionkey,
IsHighestDate = false,
SecondCityRates = null,
RateCount = 0
}).ToList();
var topCityTaxes = cityTaxInformationList.GroupBy(x => x.CityMasterKey, (Key, grp) => grp.OrderByDescending(y => y.TransactionEffectiveDate).First()).ToList();
foreach (var tx in cityTaxInformationList)
{
tx.IsHighestDate = topCityTaxes.Exists(x => x.TransactionEffectiveDate == tx.TransactionEffectiveDate && x.CityMasterKey == tx.CityMasterKey);
if (tx.IsHighestDate == true)
{
tx.RateCount = cityTaxInformationList.Where(x => x.IsHighestDate == false && tx.CityMasterKey == x.CityMasterKey).Select(x => x.TransactionStickTax).Count();
tx.SecondCityRates = string.Join(", ", cityTaxInformationList.Where(x => x.IsHighestDate == false && tx.CityMasterKey == x.CityMasterKey)
.Select(x => String.Format("{0:0.00000}", x.TransactionStickTax + " " + "(" + String.Format("{0:M/d/yyyy}", x.TransactionEffectiveDate) + ')')));
if (tx.SecondCityRates == "")
{
tx.SecondCityRates = "None";
}
}
}
var TopCityTaxInformationList = cityTaxInformationList.GroupBy(x => x.CityMasterKey, (Key, grp) => grp.OrderByDescending(y => y.TransactionEffectiveDate).First()).ToList();
return TopCityTaxInformationList;
有更有效的方式执行此操作吗?我正在查看一份包含80,000条记录的列表,并循环显示每条记录,每一条记录都是破碎性能。
答案 0 :(得分:4)
for
循环没有破坏您的性能,使用topCityTaxes
进行查找。它会查看整个列表以查找值(3次!!)。将topCityTaxes
切换到字典,按CityMasterKey
键入并进行查找。
答案 1 :(得分:1)
问题不在于foreach
循环,而是循环内部的内部 - 对整个列表进行了大量无效的LINQ查询。
看看你在里面做什么以及你从函数中返回什么,你甚至不需要@Kyle W建议的查找结构,你只需要一个正确的处理算法。
这是IMO相当于你正在做的事情
//Build City Taxes List
var cityTaxInformationList = ...;
// Build and return Top City Tax Information List
var topCityTaxInformationList = cityTaxInformationList.GroupBy(x => x.CityMasterKey, (key, elements) =>
{
var elementList = elements.OrderByDescending(e => e.TransactionEffectiveDate).ToList();
var first = elementList[0];
first.IsHighestDate = true;
first.RateCount = elementList.Count - 1;
first.SecondCityRates = first.RateCount == 0 ? "None" : string.Join(", ",
elementList.Skip(1).Select(x => string.Format("{0:0.00000} ({1:M/d/yyyy})",
x.TransactionStickTax, x.TransactionEffectiveDate)));
return first;
}).ToList();
return topCityTaxInformationList;
原理是原始代码中的所有逻辑都是针对共享相同CityMasterKey
的元素,而GroupBy
完全为您分离。