Фактът, че получавате ObjectDisposedException
извън контекста, показва, че Entity Framework се опитва да зареди обекта, към който ProductVariant.OrderProduct
се отнася, чрез мързеливо зареждане от базата данни.
Сега, това не означава непременно - и това твърдение звучи странно - че ProductVariant.OrderProduct
вече не е заредено и попълнено с правилния обект. Вероятно е така, защото това е просто обратното свойство на OrderProduct.ProductVariant
, което сте заредили чрез нетърпеливо зареждане. За релации "един към един" и "един към много" EF автоматично ще попълни свойствата за обратна навигация, когато се зареди свойство за навигация ("Коригиране на връзката").
Въпреки че свойството за обратна навигация е попълнено, то не е непременно маркирано като заредено, което е флаг, поддържан от контекста за всяко свойство за навигация, който казва на EF дали дадено свойство за навигация трябва да бъде заредено от базата данни чрез отложено зареждане когато имате достъп до него във вашия код.
За връзка "един към много" например лесно се вижда, че EF не трябва да маркира навигационно свойство като заредено, когато се попълни поради коригиране на връзката. Например: Ако заредите поръчка, включително нейния клиентски номер - context.Orders.Include("Customer").Single...
- колекцията Orders
в нетърпеливо заредения клиент ще съдържа тази заредена поръчка (поради коригиране на връзката). Но тази единична поръчка най-вероятно не е единствената поръчка, която този клиент има (или поне EF не може да знае дали това е единствената поръчка или има още в базата данни). Ако получите достъп до колекцията Customer.Orders
, обикновено очаквате, че не само тази единична поръчка ще бъде върната, но и всички поръчки на клиента - с други думи, вие очаквате да се случи заявка за отложено зареждане, която зарежда останалите поръчки на клиента от базата данни.
Сега, този аргумент не е наистина убедителен за връзка едно към едно, защото за такава връзка е ясно, че не може да има повече от един свързан обект в базата данни. И така, защо EF ще иска да изпълни заявка за отложено зареждане, ако този единствен свързан обект вече е зареден?
Не знам защо EF все още се опитва да зареди свойството за обратна навигация за връзката едно към едно, но вероятно просто не прави разлика между връзката един към много и връзката едно към едно в това отношение . Може би EF следва общото правило, че ако основната страна на връзката е попълнена от корекция на връзката, тя не е маркирана като заредена и мързеливото зареждане ще се случи във всеки случай, когато получите достъп до нея. (Наистина не мога да видя от вашия кодов фрагмент дали OrderProduct
или ProductVariant
е главният, това е само предположение.)
Както и да е, във вашата ситуация бих деактивирал мързеливото зареждане или дори създаването на прокси (което включва деактивиране на мързеливото зареждане), защото използвате Include
вътре в блок using
и мързеливото зареждане няма полза тук. Изключението, което имате, трябва да изчезне тогава:
using (var context = new MyContext())
{
context.Configuration.ProxyCreationEnabled = false;
var orders = context.Order.Include("OrderProduct")
.Include("OrderProduct.ProductVariant")
.Where(some query)
.ToList();
}
person
Slauma
schedule
27.09.2013