Я начал работать недавно в новом проекте, где у нас есть тысячи строк устаревшего кода. Мы сталкиваемся с несколькими проблемами производительности. Я решил взглянуть на код и увидел следующее. Существует класс:Возможные проблемы с производительностью с кодом C# в устаревшем проекте
public class BaseDataAccess
{
private Database dB;
public Database DB
{
get
{
if (dB == null)
{
dB = DatabaseFactory.CreateDatabase();
}
return dB;
}
}
}
И многие классы потомков, которые наследуются от предыдущего базового класса. Внутри эти другие классы использовать свойства БД, например:
DataSet ds = DB.ExecuteDataSet(spGetCustomersSortedByAge);
Наконец, существует огромный класс (5000 строк кода) с десятками способов, как следующее:
public void ProcessPayments()
{
try
{
List<Employee> employees = new EmployeesDA().SelectAll(null);
foreach (Employee employee in employees)
{
employee.Account = new MovementsDA().SelectAll(employee.Id, DateTime.Now);
...
City city = new CitiesDA().Select(zone.cityId);
...
Management m = new ManagmentDA().Select(city.id);
}
}
catch (Exception ex)
{
...
}
}
Примечание в предыдущем методе EmployeesDA, MovementsDA, CitiesDA и ManagmentDA все являются наследниками BaseDataAccess и внутренне используют свои соответствующие свойства БД. Также обратите внимание, что они постоянно создаются внутри циклов foreach (много раз в пределах 2 уровней гнездования).
Я думаю, что сама инстанция подозрительна, но меня больше беспокоит, что происходит с подключениями к базе данных здесь? Является ли каждый экземпляр DA открытием нового базового соединения? Насколько плохо этот код?
В качестве побочного примечания о решении, которое я рассматривал в случае, если этот код должен быть исправлен: я рассматривал возможность создания каждого конструктора частным образом, поэтому компилятор начинает жаловаться на экземпляры и реорганизовывать экземпляры с вызовами метода GetInstance (singleton pattern), чтобы избежать воссоздания объектов и базовых соединений. Но я не уверен, что это может быть опасно, например, если соединения могут быть закрыты. В текущем коде нет этой проблемы из-за того, что все время происходит.
Существует много неправильного подхода к этому подходу, но вы правы, если метод 'DatabaseFactory.CreateDatabase();' возвращает новое подключенное соединение с базой данных для каждого вызова, тогда у вас есть большая проблема с соединением. –
Еще одна проблема, с которой вы столкнулись, - это поддержка транзакций. Не следует ли «ProcessPayments» убедиться, что все происходит в одной транзакции? Или, по крайней мере, одна транзакция на одного сотрудника или какая-то такая вещь? –
Правильный способ справиться с этим заключается в том, чтобы приступить к тому, что у вас есть подключенное состояние, видимое в вашей программе, таким образом, что оно должно управляться. –