Entity Framework Entity не показывает свойства связанных объектов - PullRequest
1 голос
/ 15 декабря 2010

Я новичок в Entity Framework.Я создал многоуровневое приложение в MVC, используя Ninject.
У меня есть три таблицы в базе данных.Скажем, Таблица A, Таблица B и Таблица C.

Table A has a foreign key relating it to Table B  
Table B has a foreign key relating it to Table C

Table A => Table B => Table C

Мое приложение имеет «службу», которая будет вызываться из контроллера MVC.
Служба действует как хранилище для каждого объекта (например, TableAService)., TableBService), который отвечает за создание, чтение, обновление или удаление объектов из EF DataContext, а также за возможное выполнение бизнес-логики для этих объектов.

В моем контроллере MVC у меня есть ссылка на соответствующую службу.Например:

private TableAService _tableAService;

public TableAController(EFDataContext dataContext)
{
    _tableAService = new TableAService(dataContext);
}

public ActionResult Index()
{
    return View();
}

TableAService будет выглядеть примерно так:

private EFDataContext _dataContext;

public TableAService(EFDataContext dataContext)
{
    _dataContext = dataContext;
}

public TableA GetById(int tableAId)
{
    _dataContext.TableA.SingleOrDefault(ta => ta.TableAId == tableAId);
}

Я понимаю, что служба примера будет тесно связана с источником данных, моя фактическая реализация немного отличается, но концепциято же самое, у меня есть служба с dataContext, из которой я хотел бы вернуть сущности.

ВОПРОС: - Когда я в методе GetById в TableAService, SingleOrDefault дает мне свойство навигации TableB,который позволяет мне получить доступ ко всем свойствам TableB, включая свойство навигации TableC.

Однако, когда я передаю TableA обратно в контроллер, я не могу получить доступ ни к одному из свойств TableB.

В пределахСлужба, которую я также пробовал:

private ObjectSet<TableA> _objSet = _dataContext.CreateObjectSet<TableA>();

и

return _objSet.SingleOrDefault(ta => ta.TableAId == tableAId);

Кажется, это не имеет никакого значения для возможности доступа к свойству навигации TableC в TableB из сущности TableA.

Любая помощь будет принята с благодарностью!

Приветствия,

Джеймс

Ответы [ 3 ]

3 голосов
/ 15 декабря 2010

Содержимое свойства навигации может быть загружено только в рамках активного ObjectContext.

Это необходимо, потому что фактические строки будут извлечены в оба конца в базу данных.
В вашем случае вы пытаетесь получить доступ к свойству навигации после того, как ObjectContext , который использовался для извлечения сущностей в первую очередь, был удален, а соединение потеряно.

Предполагая, что вы используете Entity Framework 4 , есть 2 решения этой проблемы:

  • Готовность к загрузке: связанные сущности загружаются заранее, то есть вы явно указываете Entity Framework загружать все связанные сущности во время получения результатов запроса.
    Это можно сделать в несколькими различными способами: путем включения связанных объектов в проекцию запроса, путем вызова метода ObjectQuery.Include или путем вызова метода Load для свойства навигации, в качестве альтернативы ObjectContext.LoadProperty метод.
  • Ленивая загрузка: связанные объекты загружаются по требованию, то есть при первом обращении к геттеру навигационного свойства. Обратите внимание, что это все еще должно быть сделано в рамках ObjectContext.

В вашем случае энергичная загрузка с использованием метода Включить , вероятно, является наиболее подходящим решением:

public TableA GetById(int tableAId)
{
    return _dataContext.TableA
        .Include("TableB.TableC") // use dot-notation to specify depth in the object graph
        .SingleOrDefault(ta => ta.TableAId == tableAId);
}

Связанные ресурсы:

2 голосов
/ 15 декабря 2010

Попробуйте изменить метод GetById на:

public TableA GetById(int tableAId)
{
    return _dataContext.TableA.Include("TableB").SingleOrDefault(ta => ta.TableAId == tableAId);
}

Если вы также хотите получить запись TableC, используйте:

public TableA GetById(int tableAId)
{
    return _dataContext.TableA.Include("TableB.TableC").SingleOrDefault(ta => ta.TableAId == tableAId);
}

Причина в том, что Entity Framework«отложенная загрузка», что означает, что материал не загружается из базы данных, пока он вам действительно не понадобится.Проблема в том, что после выхода из сервиса контекст данных больше не существует для получения записи таблицы B.Метод Include инструктирует EF немедленно загружать данные из связанных таблиц.

0 голосов
/ 22 декабря 2010

Потребовалось некоторое копание, но проблема, с которой я столкнулся, заключалась в том, что мое приложение не ссылалось на System.Data.Entity.

Добавление ссылки на приложение позволило мне получить доступ к свойствам связанных объектов из контроллера.

Спасибо за ваши ответы, ребята, они помогли мне исключить возможности. Я проголосовал за каждого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...