2013-05-08 2 views
1

Так у меня есть следующие 2 модели:В EF/MVC можно ли редактировать виртуальную собственность?

[Table("Company")] 
public class Company { 
    public virtual List<UserAccount> Users { 
     get { 
      // I load my users here 
     } 
    } 
} 
[Table("UserAccount")] 
public class UserAccount { 
    public string email { get; set; } 
} 

На мой взгляд, я стараюсь, чтобы изменить его:

@model MyXsite2013.Company 
<table> 
foreach (UserAccount ua in Model.Users) { 
    <tr class="noRowHover"> 
     <td> 
      @Html.TextBoxFor(modelItem => ua.email) 
     </td> 
    </tr> 
} 
</table> 

И постбэка, я пытаюсь сохранить:

public ActionResult Edit(Company companyModel) { 
    Company companyContext = database.Companies.Find(companyModel.ID); 
    database.Entry(companyContext).CurrentValues.SetValues(companyModel); 
    companyContext.IsActive = true; 
    database.SaveChanges(); 
} 

Это, конечно, не сохраняет изменения для Пользователей, на самом деле он даже не видит изменений.

+0

Согласно к моему пониманию вашего вопроса. Мы не можем использовать эту страсть, потому что виртуальное ключевое слово используется для целей внешнего ключа. если мы используем виртуальное ключевое слово, это означает, что коллекция будет ленивой загрузкой. пожалуйста, поправьте меня, если я вернусь. –

+0

PLease прочитал [this] (http://stackoverflow.com/questions/4949991/binding-collections-in-mvc) и [this] (http://stackoverflow.com/questions/6852559/mvc3-modelbinding-to- а-коллекция отправленный-обратно-с индексом зазоров). После успешной привязки в post post вы прочтете «Компания», затем обновите ее свойства и коллекцию (merge \ removeAll + add). – lavrik

+0

Вы должны обернуть свою форму в '@using (Html.BeginForm()) {}'. –

ответ

1

Ваша проблема в том, что вы неправильно пишете свое мнение. Если вы хотите связать модель, содержащую список, вы должны установить для них специальные имена.

Что-то вроде:

@model MyXsite2013.Company 
<table> 
@{ 
    var i=0; 
} 
@foreach (UserAccount ua in Model.Users) { 
    <tr class="noRowHover"> 
     <td> 
      <input type="text" name="Model.Users[@i].email"/> 
     </td> 
    </tr> 
    i++; 
} 
</table> 

Более подробная информация по этой теме here

Update

Вы можете использовать методы HtmlHelper:

@using(Html.BeginForm("Post", "Home", FormMethod.Post)) 
{ 
    int i = 0; 
    foreach (var ua in Model.Users) 
    { 
     @Html.TextBox(string.Format("Model.Users[{0}].email", i), ua.email) 
     i++; 
    } 
    <button type="submit">Submit</button> 
} 

И не должно быть публичным сеттер:

[Table("Company")] 
public class Company { 
    public virtual List<UserAccount> Users { 
     get; 
     set; 
    } 
} 
+0

Можете ли вы прояснить этот раздел: , я не верю, что это работает. – Bill

+0

, конечно, должно быть , –

+0

Я добавляю пример кода, который генерирует правильную разметку с помощью методов HtmlHelper. –

0
  1. Вашей модели Компании Собственность пользователей нуждается в общественные сеттерах. Без него модельное связующее не сможет создать новый экземпляр List для заполнения.

  2. Вы не можете использовать цикл foreach в своем представлении, потому что помощники html не будут отображать правильные метки, необходимые для правильной отправки сообщений. Вместо этого вам нужно использовать регулярный цикл.

0

Я последовал ответ предоставленный Кирилл Bestemyanov, но сделал некоторые изменения:

[Table("Company")] 
public class Company { 
    public virtual List<UserAccount> Users { 
     get; 
     set; 
    } 
} 

и вид:

@model MyXsite2013.Company 
<table> 
@{ 
    var i=0; 
} 
@foreach (UserAccount ua in Model.Users) { 
    <tr class="noRowHover"> 
     <td> 
      <input type="text" name="Users[@i].email" value="@ua.email"/> 
     </td> 
    </tr> 
    i++; 
} 
</table> 

И в постбэк:

foreach (UserAccount ua in companyModel.Users) { 
    UserAccount UA_Context = database.UserAccounts.Find(ua.ID); 
    database.Entry(UA_Context).CurrentValues.SetValues(ua); 
} 
database.SaveChanges(); 
Смежные вопросы