IQueryable Entity Framework POCO Mappings - PullRequest
       61

IQueryable Entity Framework POCO Mappings

1 голос
/ 08 ноября 2010

Я использую ASP.NET MVC2 с EF4. Мне нужно создать POCO для двух моих классов PersonP и AddressP, которые соответствуют их «сложным» классам EF4 (которые включают в себя такие вещи, как свойства навигации и OnPropertyChanged ()). Отображение только PersonP само по себе работает нормально, но PersonP содержит AddressP (внешний ключ) - как мне сопоставить это с помощью выражения IQueryable?

Вот что я пробовал:

class AddressP
{
 int Id { get; set; }
 string Street { get; set; }
}

class PersonP
{
 int Id { get; set; }
 string FirstName { get; set; }
 AddressP Address { get; set; }
}

IQueryable<PersonP> persons = _repo.QueryAll()
    .Include("Address")
    .Select(p => new PersonP
{
 Id = p.Id,
 FirstName = p.FirstName,
 //Address = p.Address <-- I'd like to do this, but p.Address is Address, not AddressP
 //Address = (p.Address == null) ? null :
 //new AddressP    <-- does not work; can't use CLR object in LINQ runtime expression
 //{
 // Id = p.Address.Id,
 // Street = p.Address.Street
 //}
});
  1. Без .Include("Address") Я бы не стал ничего извлекать из таблицы адресов, это правильно?

  2. Как мне сопоставить Address с AddressP внутри PersonP, используя оператор Select() выше?

Спасибо.

1 Ответ

1 голос
/ 08 ноября 2010
  1. Это правильно, если вы отключили Ленивая загрузка или контекст вашего объекта уже удален и не может быть использован для работы Ленивой загрузки.

  2. Да, это не будет работать, так как сначала вам нужно выполнить запрос, а затем начать отображать его, в противном случае ваша логика отображения будет принята для запуска в базе данных, следовательно, исключение.
    Примерно так будет работать:
// First we execute the query:
IQueryable<PersonP> persons = _repo.QueryAll().Include("Address").ToList();

// Now we have a IEnumerable and we can safely do the mappings:
persons.Select(p => new PersonP
{
    Id = p.Id,
    FirstName = p.FirstName,
    Address = (p.Address == null) ? null : new AddressP()
    {
        Id = p.Address.Id,
        Street = p.Address.Street
    }
}).ToList();

Хотя это решение и поможет, но если вы хотите иметь классы POCO, вам определенно следует рассмотреть возможность использования поддержки POCO EF4.0и использовать классы POCO непосредственно с EF вместо того, чтобы отображать их потом.Хорошее место для начала было бы это пошаговое руководство:
Пошаговое руководство: Шаблон POCO для Entity Framework

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