2014-01-27 3 views
1

Итак, у меня есть проблема с сохранением данных, содержащих связанные объекты, когда я сохраняю новое отношение.Обновление связанных данных с использованием MVC 4 и Entity Framework?

Exemple:

Сущности:

public class Project 
{ 
    public int Id { get; set; } 
    public int Code{ get; set; } 
    public string Description{ get; set; } 

    public virtual Client Client { get; set; } 
} 


public class Client 
{ 
    public int Id { get; set; } 
    public int Code { get; set; } 
    public string Name { get; set; } 
} 

ГЭТ Контроллер:

public ActionResult Create() 
{ 
    PopulateDropDownClienteList(String.Empty); //Returns to ViewBag to create a combobox .in view 
    return View(); 
} 

Взгляд:

@Html.DropDownListFor(m => m.Client.Id, new SelectList(ViewBag.Client_Id, "Id", "Name"), new { Name = "Client.Id" }); 

Контроллер POST:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(string command, Project project) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       projectRepository = new ProjeRepository(); 
       Project pro = projectRepository.ReturnByCode(project.Code); 

       if (pro == null) 
        projectRepository.Save(project); 
       else 
        projectRepository.Update(project); 

       PopulateDropDownClienteList(String.Empty); 

       Return View(); 

      } 
      else 
      { 
       return View(project); 
      } 
     } 
     catch (Exception ex) 
     { 
      return View(); 
     } 
    } 

Поэтому, когда я сохраняю данные, клиент не связан с проектом. просто создавая новый пустой клиент.

+0

Что происходит в 'projectRepository.Save'? –

+2

EF уже отвлечен слишком много. Вам не нужен репозиторий шаблон поверх него –

+0

Project.Save: общественного аннулируются Сохранить (Проект) { попробовать { _dao = новый контекст приложения(); _dao.Project.Add (проект); _dao.SaveChanges(); } catch (исключение ex) { throw new Exception (ex.Message); } } – jocieldo

ответ

1

Вы Project Сохранить код не обновляет объект, это ДОБАВЛЕНИЕ новый один все время.

Вы должны иметь логику обновления, похожий на следующих основаниях -

Чтобы добавить новый FK запись и связать его с родительской записью -

var entity = entities.Students.Where(p => p.Id == "2").First(); 
entity.StudentContact = new StudentContact() { Contact = "xyz", Id = "2" }; 

entities.Students.Attach(entity); 
var entry = entities.Entry(entity); 
// other changed properties 
entities.SaveChanges(); 

обновить запись FK с новыми подробностями -

var entity = entities.Students.FirstOrDefault(); 
entity.StudentContact.Contact = "ABC"; 

entities.Students.Attach(entity); 
var entry = entities.Entry(entity); 
entry.Property(e => e.StudentContact.Contact).IsModified = true; 
// other changed properties 
entities.SaveChanges(); 

Приведенный выше код, у меня есть студенческие записи, которые имеют FK с StudentContacts. Я обновил контактную информацию учащегося, а затем обновил его до базы данных с помощью ATTACH.

+0

Проблема заключается в том, когда я создаю новый проект для клиента. Субъект, когда я отправить форму на взгляд, возвращение: - Project.Id = нуль - Project.Code = 0001 - Project.Description = "Простой текст" - ** Project.Client.Id = 1 ** Клиент с идентификатором «1» выходит. Но, когда я его сохраняю, создается новый пустой клиент, и референс не создается для существующего клиента. – jocieldo

+0

@ user3198710, вот что я вам говорю. Не используйте ADD - _dao.Project.Add (проект); вместо этого используйте Attach, как показано выше. – ramiramilu

+0

Если бы мой ответ помог вам, можете ли вы пометить его как ответ, который поможет другим легко найти ответы. – ramiramilu

1

У вас здесь много проблем, поэтому позвольте мне разбить их.

Прежде всего, никогда не ловят Exception (по крайней мере, не бросая его снова). Есть две очень важные вещи об использовании блоков try...catch: вы должны только обернуть код, в котором вы ожидаете исключения (не почти весь ваш метод, как вы это делали здесь), и вы должны поймать только то особое исключение, которое вы ожидаете (а не базовый тип Exception). Когда вы поймаете Exception, любое исключение, которое может быть создано из вашего кода, будет поймано, и в этом случае просто будет отброшено, что означает, что вы действительно никогда не узнаете, работает ли этот код вообще.

Во-вторых, у вас есть прекрасный метод, который генерирует раскрывающийся список вариантов, но никогда не сохраняет выбор пользователя в любом месте. Чтобы понять, почему, вам нужно остановиться и подумать о том, что здесь происходит. Элемент выбора HTML имеет строковое значение и текстовый текст или компонент метки. Он не поддерживает передачу полных объектов туда и обратно. Я не могу видеть, что делает ваш метод PopulateDropDownClienteList, но то, что он должен делать это создание IEnumerable<SelectListItem>, где каждый элемент получает его свойство Text установить все, что вы хотите отобразить и его Value собственности на ПК в Client. Однако, как только у вас есть это, вам нужно некоторое свойство на Project, чтобы отправить его обратно. Ваш виртуальный Client не будет работать, так как вам нужен полный экземпляр Client, который ваша форма никогда не будет иметь. Таким образом, у вас есть два варианта:

  1. Внедрение модели представления для подачи на просмотр (и принятия в сообщении). В этой модели просмотра, помимо всех других редактируемых полей, вы будете включать что-то вроде ClientId, которое будет int, и вы привяжете его к выпадающему списку. После того, как вы используете метод post, вы сопоставьте все опубликованные значения с экземпляром проекта, а затем используйте ClientId для поиска клиента из базы данных. Затем вы устанавливаете результирующий клиент в качестве значения для вашего Client и сохраняете, как обычно.

  2. Вы немного измените свою базу данных. Когда вы просто указываете виртуальную, Entity Framework smartly создает внешний ключ и столбец для хранения этих отношений для вас за кулисами. Это здорово, но в таких ситуациях, когда вам действительно нужно получить доступ к этому столбцу внешнего ключа, вы ввернуты.Таким образом, это явно определить свойство для хранения этих отношений в вашей модели и сообщить Entity Framework использовать это вместо создания собственного.

    [ForeignKey("Client")] 
    public int ClientId { get; set; } 
    public virtual Client Client { get; set; } 
    

    При том, что теперь вы можете напрямую использовать ClientId, не заботясь о заполнении Client. Вы снова привязываете свой раскрывающийся список к ClientId, но теперь вам не нужно явно искать клиента из базы данных. Entity Framework просто сохранит ClientId, как и в случае с базой данных, а затем восстановит Client на основе этого, когда вы снова просмотрите проект в будущем.

+0

Спасибо всем. не удалось решить. заполнял клиента другим контекстом, и должен быть таким же всегда ... Спасибо! – jocieldo

Смежные вопросы