На самом деле у вас есть потенциально преждевременная ликвидация, а не поздняя, поскольку сущности, участвующие в закрытии, назначенном источнику данных, означают, что он выходит из области действия.
Вы тогда получили сущности, которые не будут удалены в их реальной области действия, на что жалуется анализ, но вряд ли это будет проблемой по сравнению с тем фактом, что он утилизируется перед последним использованием.
Опции:
Оставьте все как есть. Если приведенное выше работает, то это вероятно потому, что удаление не влияет на состояние, необходимое для работы замыкания. Это рискованно. Делать ставку на «вероятно» — не лучшая идея, и со временем это может измениться. (Я могу вспомнить один случай, когда использование объекта после утилизации имеет смысл, но это неясно, и в любом случае это не то, что у вас есть).
Принудительно выполнить запрос. Вызов ToList()
или ToArray()
в запросе запустит его и создаст результат в памяти, который затем будет использоваться в качестве источника данных. В лучшем случае это будет менее эффективно как в пространстве, так и во времени. В худшем случае это может быть ужасно (в зависимости от размера результатов, с которыми вы имеете дело).
Убедитесь, что элемент управления завершает использование своего источника данных до выхода из области действия. Затем очистите источник данных. В зависимости от рассматриваемого элемента управления и некоторых других факторов (в частности, если он имеет явный метод DataBind()
) сделать это может быть тривиально, невозможно или где-то посередине.
Поместите сущность в переменную экземпляра. Реализовать IDisposable
. В вашем методе Dispose()
назовите его методом Dispose()
. Не добавляйте финализатор для этого, так как вы только удаляете управляемый объект.
Создайте перечисляемый метод, который обертывает запрос (и использование), а затем выполняет yield return
для каждого элемента, возвращаемого запросом. Используйте это как источник данных.
5 кажется лучшим выбором для большинства случаев. Его преимущество заключается в том, что код сильно не меняется, но при этом не добавляются (потенциально большие, в зависимости от данных) накладные расходы числа 2. Обратите внимание, что просто вызов AsEnumerable
(который почти влияет на порядок выполнения) не будет иметь такого же эффекта, так как закрытие по-прежнему оставит блок невыполненным.
Изменить: перечисляемое, обертывающее запрос, будет выглядеть так:
private IEnumerable GetSessions()
{
using (var entities = new DbEntities(Properties.Settings.Default.UserConnectionString))
{
entities.CommandTimeout = 7200;
var sessions = from t in entities.TableName
where t.UserSession.Id == _id && t.Parent == 0
group t by new { t.UserSession, t.UserSession.SessionId } into sessionGroup
select new
{
Id = sessionGroup.Key.UserSession,
Session = sessionGroup.Key.SessionId
};
foreach(var sess in sessions.Where(x => x.Time > 0.00))
yield return sess;
}
}
Затем вы должны установить для изменения SessionSummary_Load значение:
private void SessionSummary_Load(object sender, EventArgs e)
{
summaryDataGridView.DataSource = GetSessions();
summaryDataGridView.Columns[4].DefaultCellStyle.Format = "N2";
summaryDataGridView.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
}
}
Надеюсь, это решит проблему, потому что entities
никогда не выходит за рамки using
.
person
Jon Hanna
schedule
02.09.2010