MVC 3 с Entity Framework и редактированием нескольких объектов приводит к «нарушению ограничения ссылочной целостности» - PullRequest
2 голосов
/ 01 сентября 2011

У меня есть проект MVC 3, над которым я работаю, используя Entity Framework в качестве моей модели. У меня есть объект «Работодатель», который имеет «Адрес» и «Почтовый адрес», который я хотел бы отображать (просматривать) и обновлять (редактировать) одновременно (то есть на странице с информацией об работодателе и адресах, которая обновляется одновременно )

Кажется, мой взгляд работает нормально:

var employer = (from e in entities.Employers.Include("Address").Include("PostalAddress")
                where e.EmployerNumber == employerNumber
                select e).First();    
return View(employer);

Мои изменения отображаются нормально (т. Е. Все текстовые поля заполнены как работодателем, так и адресом)

[HttpPost]
public ActionResult Edit(Employer employer)
{
    if (ModelState.IsValid)
    {
        entities.Employers.Attach(employer);
        entities.ObjectStateManager.ChangeObjectState(employer, EntityState.Modified);
        entities.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(employer);
}

Но когда я иду на сохранение, я получаю следующее исключение для строки entity.Employers.Attach (работодатель):

Произошло нарушение ограничения ссылочной целостности: свойство значения, которые определяют ссылочные ограничения, не согласованы между главным и зависимым объектами в отношениях.

Когда я смотрю на объект работодателя, который он пытается прикрепить, кажется, что он "потерял" элементы Address и PostalAddress.

Это мой первый проект MVC 3, поэтому любая помощь будет оценена.

Вид страницы редактирования выглядит следующим образом

@model MyProject.BusinessObjects.Employer           
@{ ViewBag.Title = "Edit Employer Details"; }

<h2>Edit Employer Details</h2>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>

        <legend>Employer</legend>
            <div class="editor-label">Name</div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>

            <fieldset>
                <legend>Address</legend>
                    <div class="editor-label">Line One</div>
                    <div class="editor-field">
                        @Html.EditorFor(model => model.Address.LineOne)
                        @Html.ValidationMessageFor(model => model.Address.LineOne)
                    </div>

                    <div class="editor-label">Line Two</div>
                    <div class="editor-field">
                        @Html.EditorFor(model => model.Address.LineTwo)
                        @Html.ValidationMessageFor(model => model.Address.LineTwo)
                    </div>

                    <div class="editor-label">Suburb</div>
                    <div class="editor-field">
                        @Html.EditorFor(model => model.Address.Suburb)
                        @Html.ValidationMessageFor(model => model.Address.Suburb)
                    </div>

                    <div class="editor-label">State</div>
                    <div class="editor-field">
                        @Html.EditorFor(model => model.Address.State)
                        @Html.ValidationMessageFor(model => model.Address.State)
                    </div>

                    <div class="editor-label">Post Code</div>
                    <div class="editor-field">
                        @Html.EditorFor(model => model.Address.PostCode)
                        @Html.ValidationMessageFor(model => model.Address.PostCode)
                    </div>
            </fieldset>

        <p>
            <input type="submit" value="Save Changes" />
        </p>
    </fieldset>
}

Ответы [ 2 ]

3 голосов
/ 01 сентября 2011

Не могли бы вы опубликовать свой файл бритвы? Я предполагаю, что привязка модели не работает должным образом. Как вы создаете форму?

Я бы предложил вам использовать шаблон «ViewModel» для решения этой проблемы.

Создайте класс, который содержит свойства, отображаемые пользователю, и в действии получите этот объект и «трансформируйте» его в объект модели.

Было бы что-то вроде этого:

Представьте, что у вас есть эти классы:

public class Employee{
   public string Name {get; set;}
   public Address Address {get; set;}
}
public class Address {
   public string Street {get; set;}
}

Чем ваша модель будет:

public class EmployeeViewModel{
   public string Name {get; set;}      
   public string Street {get; set;}
}

Вы можете использовать Automapper для простого преобразования между этими объектами.

2 голосов
/ 01 сентября 2011

Я думаю, что у вас проблемы с ModelBinder.

Возможно, он не работает со сложными типами для вас (я предполагаю, что Address и PostalAddress - навигационные свойства Employer).

youможно попробовать код ниже.

[HttpPost]
public ActionResult Edit(Employer employer, FormCollection col)
{
    if (ModelState.IsValid)
    {
        var emp = employer;
        //populate emp.Address and emp.PostalAddress with values from col
        entities.Employers.Attach(emp);
        entities.ObjectStateManager.ChangeObjectState(emp, EntityState.Modified);
        entities.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(employer);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...