开发者

EF 4.1 Code first. Relation with other object containing required objects

I've been puzzeling and searching all afternoon, but I just can't find what I need. Consider the following code:

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; }
}

The view looks like this:

<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>

The ViewModel used for this view is:

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() });
    }

The problem is this: in my view I have a dropdownlist containing the names of perso开发者_高级运维ns that are available for a project. When a contact is selected, the id is set. Yet the ModelState is not valid because the person object throws several errors due to the fact that it's properties are required.

Is there a way to do this or do i just have to settle on the project having just the ids of person and type as reference ?

Thanx in advance


I see couple of problems with your design

Your View Model is too complicated

You are binding data to nested properties 3 or 4 levels down. View models are used to simplify the presentation logic. Your drop down list items are also included in the Model. I suggest you use ViewData or ViewBag to pass them from controller to view.

Binding DropDownLists to navigation properties

Eg: if you bind model => model.Project.Type.ID to a drop down the MVC model will have to create new instance of ProjectType to bind the property. Because of that EF will treat the ProjectType as a new entity and will try to add it. I doubt you want to add new ProjectType when you add new Project.

I suggest you add a scalar property TypeID and decorate it Required attribute

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; }
}

and then bind it

@Html.DropDownListFor(model => model.Project.TypeID, Model.ProjectTypes, new { @class = "dropDownList" })
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜