Почему простая связь модели данных сущности возвращает нуль вместо ссылки на объект? - PullRequest
7 голосов
/ 16 февраля 2009

У меня есть две простые таблицы и внешний ключ, определенный в SQL Server Express:


Продукт

  • ProductID [auto-inc]
  • Имя
  • CompanyID [not-null]

Компания

  • CompanyID [auto-inc]
  • Имя

FK_Product_Company

  • Product.CompanyID = Company.CompanyID

Я создал модель данных сущности ADO.NET и добавил в нее все таблицы. Файл .edmx показывает отношение 1-ко-многим в конструкторе. Я вручную заполнил базу данных данными, которые гарантировали бы, что у каждого продукта есть компания. Однако всякий раз, когда я пытаюсь получить доступ к компании продукта, она всегда возвращает ноль вместо экземпляра компании.

Например, при запуске следующего кода в C # возвращается ноль:

var _db = new MyDBEntities();
var product = (from p in _db.Product
               where p.ProductID == 3
               select p).First();
product.Company // == null

Есть ли какие-то шаги, которые мне не хватает, чтобы заставить это работать?

Спасибо


Вещи, которые я пробовал:


Запуск следующего SQL-кода корректно возвращает запись о компании.

SELECT Company.*
FROM Product
  LEFT JOIN Company ON (Product.CompanyID = Company.CompanyID)
WHERE Product.ProductID = 3

Следующее, что я хотел бы сделать для устранения этой проблемы, это запустить следующий код:

var _db = new MyDBEntities();
var product = (from p in _db.Product
               where p.ProductID == 3
               select p).First();
var company = (from c in _db.Company
               where c.CompanyID == product.CompanyID
               select c).First();

Однако это не компилируется, поскольку поле Product.CompanyID скрыто генератором ORM, и я не вижу опции в конструкторе, чтобы добавить его.


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

var _db = new MyDBEntities();
var company = (from c in _db.Company
               where c.CompanyID == 2
               select c).First();

Просто чтобы прояснить, Продукт с ID 3 соответствует Компании с ID 2.


Я попытался создать точно такое же отношение, используя LINQ to SQL Classes , и оно отлично работает.

Конечно, вместо того, чтобы использовать класс DB Entities, я использую класс Data Context.

Ответы [ 4 ]

11 голосов
/ 16 февраля 2009

Вам необходимо добавить метод .Include к вашему запросу.

var _db = new MyDBEntities();
var product = (from p in _db.Product.Include("Company")
               where p.ProductID == 3
               select p).First();
6 голосов
/ 18 февраля 2009

Глубокая загрузка поддерживается платформой Entity, но отложенная загрузка не поддерживается (отложенная загрузка будет поддерживаться в Entity Framework 2.0).

С Load () или .Include ("Компания"), как и в предыдущих сообщениях, говорят, что это будет работать.

Вот пример того, как можно сделать структуру сущностей ленивой: http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx

1 голос
/ 17 февраля 2009

Вы можете использовать Включить, как предложено выше.

Или попробуйте позвонить

product.Company.Load () для получения объекта.

Entity Framework использует отложенную загрузку, чтобы избежать ненужных запросов до тех пор, пока объект действительно не понадобится.

Дополнительная информация об отложенной загрузке приведена здесь: http://www.code -magazine.com / article.aspx? Quickid = 0711051 & page = 4

0 голосов
/ 02 декабря 2011

Использование «Включить» требует строкового параметра, что затрудняет рефакторинг. Лучший вариант - упомянуть ваше отношение в самом предложении select:

var product = (from p in _db.Product
     where p.ProductID == 3
     select new {p.Name, Company = p.Company.Name})

Пока "Product.Company" упоминается в выражении LINQ, компилятор EF будет видеть его и загружать все упомянутые столбцы. Дополнительным преимуществом является то, что сгенерированный SQL будет содержать только те столбцы, которые вам действительно нужны (меньше трафика)

Это не сработает, если вам нужно читать и писать ваши объекты.

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