IQueryable Entity Framework POCO Mappings

Я использую 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. Это правильно, если вы отключили Lazy Loading или контекст вашего объекта уже удален и не может быть использован для работы Lazy Loading.

  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

Другие вопросы по тегам