Проблема с навигационными свойствами (EF.DbContext) через WCF
От: SeLo  
Дата: 09.10.15 11:26
Оценка:
Привет, проблема с EF-объектами, точнее с навигационными свойствами (Db-Context) через сервис WCF.
Сущности сгенерированы по базе данных автоматически. DBContext сконфигурирован так:

result.Configuration.LazyLoadingEnabled = false;
result.Configuration.ProxyCreationEnabled = false;

"Корневые" объекты получаю через метод 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
От: SeLo  
Дата: 09.10.15 13:41
Оценка:
После долгих ковыряний пришел к выводу, что проблема лежит в навигационных свойсвах "дочерних" таблиц. Т.е. если в навигационном поле в свою очередь имеются навигационные поля, то они приводят к описанным проблемам. Конечно, можно через рефликсию копировать все не навигационные поля (кстати по флагу IsVirtual легко определяются), но все еще надеюсь услышать другой, нормальный способ решения проблемы.
Re[2]: Проблема с навигационными свойствами (EF.DbContext) через WCF
От: SeLo  
Дата: 09.10.15 14:58
Оценка:
Кажется разрешил проблему, она заключалась в циклических ссылках.
Для решения немного подправил TT модели, так что к классам добавился атрибут [DataContract(IsReference=true)] и к свойствам [DataMember].
Навеяно вот этим постом:
http://stackoverflow.com/questions/5762135/ef4-cause-circular-reference-in-web-service
Re: Проблема с навигационными свойствами (EF.DbContext) через WCF
От: seimur  
Дата: 08.12.15 08:59
Оценка:
Здравствуйте, 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()
Теоретически нет разницы между теорией и практикой, но на практике она есть
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.