Как сначала работать со свойствами навигации (/внешние ключи) в коде ASP.NET MVC 3 и EF 4.1

Сначала я начал тестировать «рабочий процесс» с кодом EF.
Сначала я создал диаграмму классов. Спроектировал несколько классов - вы можете увидеть диаграмму классов здесь
Затем я использовал EF Code First, создал ЭнцКонтекст..

    public class EntsContext : DbContext
    {
        public DbSet<Project> Projects { get; set; }
        public DbSet<Phase> Phases { get; set; }
        public DbSet<Iteration> Iterations { get; set; }
        public DbSet<Task> Tasks { get; set; }
        public DbSet<Member> Members { get; set; }
    }

Следующим шагом было создание ProjectController (ASP.NET MVC3) с помощью простого действия:

public ActionResult Index()
{
    using (var db = new EntsContext())
    {
        return View(db.Projects.ToList());
    }
}

Проблема в том, что я не вижу ProjectManager (список/создание используемых лесов). Я хотел бы знать, делаю ли я это неправильно, или генерация скаффолдинга просто игнорирует мои свойства, которые не являются базовыми типами.
Хм... Это, вероятно, совершенно очевидно... потому что генератор не знает, какое свойство этого Тип должен использоваться, верно?

Что ж, тогда я мог бы немного изменить свой вопрос: каков надежный способ создания объекта Project в этом сценарии (я хочу выбрать менеджера проекта во время создания проекта)? Должен ли я сделать ViewModel для этого?


person Damb    schedule 28.03.2011    source источник
comment
В вашем контроллере вы возвращаете список проектов. Как выглядит ваш проектный класс?   -  person Pete    schedule 29.03.2011
comment
Вы можете увидеть класс на связанном изображении, содержащем диаграмму классов.   -  person Damb    schedule 29.03.2011


Ответы (2)


ProjectManager не загружается по умолчанию. Вы должны либо использовать ленивую загрузку, либо активную загрузку. Нетерпеливая загрузка загрузит ProjectManager при запросе Projects:

public ActionResult Index()
{
    using (var db = new EntsContext())
    {
        return View(db.Projects.Include(p => p.ProjectManager).ToList());
    }
}

Отложенная загрузка загрузит ProjectManager после доступа к свойству в представлении. Чтобы разрешить ленивую загрузку, вы должны создать все свои свойства навигации как virtual, но в вашем текущем сценарии это не очень хорошо, потому что:

  • Ленивая загрузка требует открытого контекста. Вы закрываете контекст перед визуализацией представления, поэтому вы получите исключение удаленного контекста.
  • Ленивая загрузка в вашем случае приводит к N + 1 запросам к БД, где N - количество проектов, потому что менеджер каждого проекта будет запрашиваться отдельно.
person Ladislav Mrnka    schedule 29.03.2011
comment
Спасибо, небольшая модификация. Include() принимает только строковый ввод — имя свойства, поэтому я переписал его на: `Include(ProjectManager). Также спасибо за подсказки, почему не ленивая загрузка в моем случае. - person Damb; 29.03.2011

Я считаю, что вам понадобится класс ProjectManager, а объект Project должен иметь свойство, указывающее на класс ProjectManager.

Что-то типа:

public class Project
{
   public string Description {get; set;}
   public Member ProjectManager {get; set;}
}
person taylonr    schedule 29.03.2011
comment
Предположим, что его класс Project выглядит так, как вы описали. Как заставить автоматически созданное представление отображать свойство «Член» в текстовом поле или что-то в этом роде? Я всегда просто делаю это вручную, потому что кажется, что мастер не может сделать это за вас. Как только вы начинаете вникать в более сложные классы, вы не можете ожидать, что IDE будет детализировать каждое отдельное свойство и создавать текстовое поле, не так ли? - person Pete; 29.03.2011
comment
Проверьте связанное изображение диаграммы классов. Я уже понял, что я верю. - person Damb; 29.03.2011