Linq принудительно загружает объекты с DefaultIfEmpty, что дает исключение ObjectDisposedException
У меня есть этот linq:
using (PlantContext context = ContextManager.GetPlantContext(plantId.PlantPath))
{
results = (from p in context.Plants
join subplant in context.Subplants on p.Id equals subplant.PlantId
join inverter in context.Inverters on subplant.Id equals inverter.SubplantId
join inverterActualData in context.InverterActualDatas on inverter.Id equals inverterActualData.InverterId into joinAll
from joinItem in joinAll.DefaultIfEmpty()
select new
{
ActualData = joinItem,
Inverter = inverter,
Subplant = subplant,
Plant = p
}).AsEnumerable().Select(r => r.Inverter).ToList();
}
После этого я хочу просмотреть результаты:
foreach (Inverter inverter in results)
{
if (inverter.InverterActualData == null)
{
}
}
Это вызывает следующее исключение в строке "if (inverter.InverterActualData == null)":
An exception of type 'System.ObjectDisposedException' occurred in System.Data.Entity.dll but was not handled in user code
Я пытаюсь получить список инверторов, но в то же время загрузить его свойства Subplant и InverterActualData. (Также для Subplant загрузите свойство Plant).
Проблема возникает, когда для Inverter нет записи InverterActualData. В этом случае исключение выдается.
Почему я хочу загрузить все данные до закрытия контекста? Потому что одна поездка в базу данных намного быстрее, чем вызов InverterActualData для каждого инвертора в отдельности.
Как видите, я пытаюсь проверить, имеет ли свойство InverterActualData значение NULL, но, по-видимому, не загружено. Исключение выдается независимо.
Я также попытался добавить:
join inverter in context.Inverters.Include(InverterExtension.Relations.InverterActualData) on subplant.Id equals inverter.SubplantId
Но это тоже не работает.
Мне кажется странным, так как в профилировщике запрос переводится так:
SELECT 1 AS [C1],
[Extent4].[InverterId] AS [InverterId],
[Extent4].[Period] AS [Period],
[Extent4].[OperatingHours] AS [OperatingHours],
[Extent3].[Id] AS [Id],
[Extent3].[InverterTypeId] AS [InverterTypeId],
[Extent3].[SubplantId] AS [SubplantId],
[Extent3].[Name] AS [Name],
[Extent2].[Id] AS [Id1],
[Extent2].[PlantId] AS [PlantId],
[Extent2].[Name] AS [Name1],
[Extent1].[Id] AS [Id2],
[Extent1].[Name] AS [Name2],
FROM [Plant] AS [Extent1]
INNER JOIN [Subplants] AS [Extent2] ON [Extent1].[Id] = [Extent2].[PlantId]
INNER JOIN [Inverters] AS [Extent3] ON [Extent2].[Id] = [Extent3].[SubplantId]
LEFT OUTER JOIN [InverterActualData] AS [Extent4] ON [Extent3].[Id] = [Extent4].[InverterId]
Что именно то, что я хочу. Кроме того, при выполнении этого запроса к БД, я получаю данные Inverter, Subplant и Plant и значения по умолчанию для InverterActualData.
В чем может быть проблема?
1 ответ
Сделал это с:
using (PlantContext context = ContextManager.GetPlantContext(plantId.PlantPath))
{
context.ContextOptions.LazyLoadingEnabled = false;
results = (from p in context.Plants
join subplant in context.Subplants on p.Id equals subplant.PlantId
join inverter in context.Inverters on subplant.Id equals inverter.SubplantId
join inverterActualData in context.InverterActualDatas on inverter.Id equals inverterActualData.InverterId into joinAll
from joinItem in joinAll.DefaultIfEmpty()
select new
{
ActualData = joinItem,
Inverter = inverter,
Subplant = subplant,
Plant = p
}).ToList().Select(r => r.Inverter).ToList();
}
Здесь "context.ContextOptions.LazyLoadingEnabled = false;" и первый "ToList()" необходимы