Код EF 4.1 первый.Связь с другим объектом, содержащим требуемые объекты - PullRequest
0 голосов
/ 06 июля 2011

Я весь день ломал голову и искал, но я просто не могу найти то, что мне нужно. Рассмотрим следующий код:

public class Project 
{
    public int ID { get; set; }

    [Required(ErrorMessage="De naam van het project is verplicht")]
    public String Name { get; set; }

    [Required(ErrorMessage = "Het projecttype is verplicht")]
    public virtual ProjectType Type { get; set; }
    public virtual ProjectStatus Status { get; set; }

    [Required(ErrorMessage="De naam van het boek is verplicht")]
    public String BookName { get; set; }
    [Required(ErrorMessage = "Het aantal te vertalen woorden is verplicht")]
    public int NrOfWords { get; set; }
    [Required(ErrorMessage = "De afgesproken prijs per woord is verplicht")]
    public int MoniesPerWord { get; set; }
    public int Progress { get; set; }
    public DateTime StartDate  { get; set; }
    [Required(ErrorMessage = "De deadline van het project is verplicht")]
    public DateTime DueDate { get; set; }
    public ICollection<DateTime> StateChangedDates { get; set; }

    [Required(ErrorMessage = "Een opdrachtgever voor dit project is verplicht")]
    public int ContactPersonID { get; set; }
    [ForeignKey("ContactPersonID")]
    public virtual Person ContactPerson { get; set; }

    public virtual Company Company { get; set; }
}

public class ProjectType
{
    public int ID { get; set; }
    [Required(ErrorMessage="Naam van projecttype is verplicht")]
    public String OptionName { get; set; }
    public String Description { get; set; }
}

public class Person
{
    public int ID { get; set; }

    public String FirstName { get; set; }
    [Required(ErrorMessage = "Achternaam is verplicht")]
    public String LastName { get; set; }
    public String PhotoFileName { get; set; }
    public DateTime? DateOfBirth { get; set; }

    public int PersonTypeID { get; set; }
    [ForeignKey("PersonTypeID")]
    [Required(ErrorMessage = "Type persoon is verplicht")]
    public virtual PersonType Type { get; set; }

    public int BillingAddressID { get; set; }
    [ForeignKey("BillingAddressID")]
    [Required(ErrorMessage = "Factuuradres is verplicht")]
    public virtual Address BillingAddress { get; set; }

    public int PostalAddressID { get; set; }
    [ForeignKey("PostalAddressID")]
    [Required(ErrorMessage = "Postadres is verplicht")]
    public virtual Address PostalAddress { get; set; }

    public virtual Company Employer { get; set; }

    [Required(ErrorMessage = "Tenminste 1 emailadres is verplicht")]
    public String EmailAddress { get; set; }
    public String PhoneNumber { get; set; }
    public String WebSite { get; set; }
    public String Comments { get; set; }

    public bool IsUser { get; set; }
}

Вид выглядит так:

<div class="editor-container">
    <div class="editor-label">
        Projecttype
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.Project.Type.ID, Model.ProjectTypes, new { @class = "dropDownList" })
        @Html.ValidationMessageFor(model => model.Project.Type.ID, " ")
    </div>
    <div class="clear"></div>
</div>
<div class="editor-container">
    <div class="editor-label">
        Opdrachtgever
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.Project.ContactPerson.ID, Model.Contacts, new { @class = "dropDownList" })
    @Html.ValidationMessageFor(model => model.Project.ContactPerson.ID, " ")
    </div>
    <div class="clear"></div>
</div>

Модель представления, используемая для этого представления:

public class ProjectViewModel
{
    public Project Project { get; set; }
    public List<SelectListItem> ProjectTypes { get; set; }
    public List<SelectListItem> ProjectStatusses { get; set; }
    public List<SelectListItem> Contacts { get; set; }

    public ProjectViewModel()
    {

        Project = new Project();
        SetLists();
    }

    public ProjectViewModel(int projectID)
    {
        ProjectRepository projectRepository = new ProjectRepository();

        Project = projectRepository.GetProjectByID(projectID);
        SetLists();
    }

    private void SetLists()
    {
        ProjectTypeRepository projectTypeRepository = new ProjectTypeRepository();
        ProjectStatusRepository projectStatusRepository = new ProjectStatusRepository();
        PersonRepository personRepository = new PersonRepository();

        ProjectTypes = new List<SelectListItem>();
        ProjectStatusses = new List<SelectListItem>();
        Contacts = new List<SelectListItem>();

        foreach (var projectType in projectTypeRepository.GetProjectTypes())
            ProjectTypes.Add(new SelectListItem() { Text = projectType.OptionName, Value = projectType.ID.ToString() });

        foreach (var projectStatus in projectStatusRepository.GetProjectStatusses())
            ProjectStatusses.Add(new SelectListItem() { Text = projectStatus.OptionName, Value = projectStatus.ID.ToString() });

        foreach (var person in personRepository.GetPeopleByIsUser(false))
            Contacts.Add(new SelectListItem() { Text = String.Format("{0} {1}", person.FirstName, person.LastName), Value = person.ID.ToString() });
    }

Проблема в следующем: на мой взгляд, у меня есть выпадающий список с именами людей, которые доступны для проекта. Когда контакт выбран, идентификатор установлен. Однако ModelState недопустим, потому что объект person выдает несколько ошибок из-за того, что его свойства являются обязательными.

Есть ли способ сделать это, или я просто должен остановиться на проекте, используя только идентификаторы человека и тип в качестве ссылки?

Спасибо заранее

1 Ответ

0 голосов
/ 06 июля 2011

Я вижу пару проблем с вашим дизайном

Ваша модель просмотра слишком сложна

Вы связываете данные с вложенными свойствами на 3 или 4 уровня ниже. Модели представлений используются для упрощения логики представления. Ваши элементы выпадающего списка также включены в модель. Я предлагаю вам использовать ViewData или ViewBag для передачи их с контроллера на просмотр.

Связывание DropDownLists со свойствами навигации

Например: если вы связываете model => model.Project.Type.ID с раскрывающимся списком, модель MVC должна будет создать новый экземпляр ProjectType, чтобы связать свойство. Из-за этого EF будет рассматривать ProjectType как новый объект и будет пытаться добавить его. Я сомневаюсь, что вы хотите добавить новый ProjectType при добавлении нового Project.

Я предлагаю вам добавить скалярное свойство TypeID и украсить его Required атрибут

public class Project 
{
    public int ID { get; set; }

    [Required(ErrorMessage="De naam van het project is verplicht")]
    public String Name { get; set; }

    public virtual ProjectType Type { get; set; }

    [Required(ErrorMessage = "Het projecttype is verplicht")]
    public String TypeID{ get; set; }
}

и затем связать его

@Html.DropDownListFor(model => model.Project.TypeID, Model.ProjectTypes, new { @class = "dropDownList" })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...