Привет, проблема с EF-объектами, точнее с навигационными свойствами (Db-Context) через сервис WCF.
Сущности сгенерированы по базе данных автоматически. DBContext сконфигурирован так:
"Корневые" объекты получаю через метод AsNoTracking(), иначе ошибка, что соединение было преждеврено закрыто.
db.TableName.AsNoTracking().Where(...).ToList();
С этим все нормально, так нужно делать что бы объекты отсоединить от контекста.
Теперь хочу загрузить навигационные свойства. Пробовал:
db.TableName.AsNoTracking().Where(...).Include("..").ToList();
или
db.TableName.AsNoTracking().Where(...).Include("..").AsNoTracking().ToList();
На сервере — все нормально, данные загружены, но клиент получает ошибку, что что соединение было преждеврено закрыто или эти свойства пустые. Предполагаю, что что-то еще держится за контекст, но что делать с этим не знаю.
Проверял через ObjectContext.ObjectStateManager.GetObjectStateEntries() — ни один из объектов в ObjectStateManager не числится.
Если же делать Include "ручным" способом, т.е. грузить объекты отдельно и присваивать их "корневому", то работает:
var rootList = db.TableName.AsNoTracking().Where(...)ToList();
foreach(var rootObj in rootList ) {
if (rootObj.Table2_ID != null) rootObj.Table2 = db.Table2.AsNoTracking().Where(x => x.ID == rootObj.Table2_ID).First()
}
Но мне такой способ не походит из-за нескольких причин. Одна из них — список Include-сущностей передается в метод как параметр, т.е. динамический.
EF используется 6.1.3, VS 2013, .NET v4.5
Как побороть, что я делаю не так?
Re: Проблема с навигационными свойствами (EF.DbContext) через WCF
После долгих ковыряний пришел к выводу, что проблема лежит в навигационных свойсвах "дочерних" таблиц. Т.е. если в навигационном поле в свою очередь имеются навигационные поля, то они приводят к описанным проблемам. Конечно, можно через рефликсию копировать все не навигационные поля (кстати по флагу IsVirtual легко определяются), но все еще надеюсь услышать другой, нормальный способ решения проблемы.
Re[2]: Проблема с навигационными свойствами (EF.DbContext) через WCF
Здравствуйте, SeLo, Вы писали:
SL>Привет, проблема с EF-объектами, точнее с навигационными свойствами (Db-Context) через сервис WCF. SL>Сущности сгенерированы по базе данных автоматически. DBContext сконфигурирован так:
SL>result.Configuration.LazyLoadingEnabled = false; SL>result.Configuration.ProxyCreationEnabled = false;
SL>"Корневые" объекты получаю через метод AsNoTracking(), иначе ошибка, что соединение было преждеврено закрыто. SL>db.TableName.AsNoTracking().Where(...).ToList(); SL>С этим все нормально, так нужно делать что бы объекты отсоединить от контекста.
SL>Теперь хочу загрузить навигационные свойства. Пробовал:
SL>db.TableName.AsNoTracking().Where(...).Include("..").ToList(); SL>или SL>db.TableName.AsNoTracking().Where(...).Include("..").AsNoTracking().ToList();
SL>На сервере — все нормально, данные загружены, но клиент получает ошибку, что что соединение было преждеврено закрыто или эти свойства пустые. Предполагаю, что что-то еще держится за контекст, но что делать с этим не знаю.
SL>Проверял через ObjectContext.ObjectStateManager.GetObjectStateEntries() — ни один из объектов в ObjectStateManager не числится.
SL>Если же делать Include "ручным" способом, т.е. грузить объекты отдельно и присваивать их "корневому", то работает:
SL>var rootList = db.TableName.AsNoTracking().Where(...)ToList(); SL>foreach(var rootObj in rootList ) { SL> if (rootObj.Table2_ID != null) rootObj.Table2 = db.Table2.AsNoTracking().Where(x => x.ID == rootObj.Table2_ID).First() SL>}
SL>Но мне такой способ не походит из-за нескольких причин. Одна из них — список Include-сущностей передается в метод как параметр, т.е. динамический.
SL>EF используется 6.1.3, VS 2013, .NET v4.5
SL>Как побороть, что я делаю не так?
Возможно AsNoTracking должен быть после Include("..")
db.TableName.Where(...).Include("..").AsNoTracking()
Теоретически нет разницы между теорией и практикой, но на практике она есть