Я использую LinqToSQL для обработки данных с SQL Server, чтобы выгрузить их на сервер iSeries для дальнейшей обработки. Подробнее об этом здесь .
Моя проблема в том, что обработка 350 строк данных занимает около 1,25 минут. Я все еще пытаюсь расшифровать результаты с помощью SQL Server Profiler, но выполняется TON запросов. Вот немного подробнее о том, что я делаю:
using (CarteGraphDataDataContext db = new CarteGraphDataDataContext())
{
var vehicles = from a in db.EquipmentMainGenerals
join b in db.EquipmentMainConditions on a.wdEquipmentMainGeneralOID equals b.wdEquipmentMainGeneralOID
where b.Retired == null
orderby a.VehicleId
select a;
et = new EquipmentTable[vehicles.Count()];
foreach (var vehicle in vehicles)
{
// Move data to the array
// Rates
GetVehcileRates(vehicle.wdEquipmentMainGeneralOID);
// Build the costs accumulators
GetPartsAndOilCosts(vehicle.VehicleId);
GetAccidentAndOutRepairCosts(vehicle.wdEquipmentMainGeneralOID);
// Last Month's Accumulators
et[i].lastMonthActualGasOil = GetFuel(vehicle.wdEquipmentMainGeneralOID) + Convert.ToDecimal(oilCost);
et[i].lastMonthActualParts = Convert.ToDecimal(partsCost);
et[i].lastMonthActualLabor = GetLabor(vehicle.VehicleId);
et[i].lastMonthActualOutRepairs = Convert.ToDecimal(outRepairCosts);
et[i].lastMonthActualAccidentCosts = Convert.ToDecimal(accidentCosts);
// Move more data to the array
i++;
}
}
Все методы Get выглядят примерно так:
private void GetPartsAndOilCosts(string vehicleKey)
{
oilCost = 0;
partsCost = 0;
using (CarteGraphDataDataContext db = new CarteGraphDataDataContext())
{
try
{
var costs = from a in db.WorkOrders
join b in db.MaterialLogs on a.WorkOrderId equals b.WorkOrder
join c in db.Materials on b.wdMaterialMainGeneralOID equals c.wdMaterialMainGeneralOID
where (monthBeginDate.Date <= a.WOClosedDate && a.WOClosedDate <= monthEndDate.Date) && a.EquipmentID == vehicleKey
group b by c.Fuel into d
select new
{
isFuel = d.Key,
totalCost = d.Sum(b => b.Cost)
};
foreach (var cost in costs)
{
if (cost.isFuel == 1)
{
oilCost = (double)cost.totalCost * (1 + OVERHEAD_RATE);
}
else
{
partsCost = (double)cost.totalCost * (1 + OVERHEAD_RATE);
}
}
}
catch (InvalidOperationException e)
{
oilCost = 0;
partsCost = 0;
}
}
return;
}
Я думаю, что сокращение количества запросов к БД должно ускорить обработку. Если LINQ делает SELECT для каждой записи, возможно, мне нужно сначала загрузить каждую запись в память.
Я все еще считаю себя новичком в C # и ООП в целом (я в основном программирую RPG на iSeries). Так что я предполагаю, что делаю что-то глупое. Можете ли вы помочь мне исправить мою глупость (по крайней мере, с этой проблемой)?
Обновление: Думал, что вернусь и сообщу вам о том, что я обнаружил. Похоже, база данных была плохо спроектирована. Что бы ни генерировал LINQ в фоновом режиме, это был крайне неэффективный код. Я не говорю, что LINQ плох, он просто плох для этой базы данных. Я перешел на быстро скомпонованную настройку .XSD, и время обработки изменилось с 1,25 до 15 секунд. После того, как я сделаю правильный редизайн, я могу только догадываться, что побрею еще несколько секунд. Спасибо всем за ваши комментарии. Я попробую LINQ снова в другой день на лучшей базе данных.