Entity Framework 4: Saving one to many entities doesn't work
Here is a common scenario
I Have these Entity User UserId UserName ... UserQuestion UserQID UserID UserQuestion UserAnswer One user can Have many question, but one question is attached to one user. In my example, I create 3 Empty entities (UserQuestion). Then I attache these question on the user. In the view, for each question, answer textbox, I Use ElementAt to specify each of the UserQuestion Entity. Why I cannot save these 3 questions In the Controllerpublic ActionResult ChooseQuestion()
{
IUserRepository repUser = new UserRepository(EntityFactory.GetEntity());
User usr = repUser.GetUserByID(Convert.ToInt32(Session["UserID"]));
usr.UserQuestions.Add(new UserQuestion());
usr.UserQuestions.Add(new UserQuestion());
usr.UserQuestions.Add(new UserQuestion());
var ViewModel = new UsrViewModel()
{
UserInfo = usr
};
return View(ViewModel);
}
[HttpPost]
public void ChooseQuestion(User UserInfo)
{
UpdateModel(User, "UserInfo");
EntityFactory.GetEntity().SaveChanges();
}
In my View
<%: Html.TextBoxFor(model => model.UserInfo.UserName)%>
...
<%: Html.TextBoxFor(model => model.UserInfo.LastName%>
...
<%: Html.TextBoxFor(model => model.UserInfo.UserPassword%>
..
<h2>Question Creation</h2>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(0).UserQuestion)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(0).UserAnswer)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(1).UserQuestion)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(1).UserAnswer)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(2).UserQuestion)%>
<%: Html.TextBoxFo开发者_StackOverflow社区r(model => model.UserInfo.UserQuestions.ElementAt(2).UserAnswer)%>
3
Based on Phil Haack's post you should just have sequential number in your name attribute like so:
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(0).UserQuestion, new {name="UserInfo.UserQuestion0.UserQuestion} )%>
Normally the built-in HtmlHelper.TextboxFor method will do the name attribute correctly if it is in a for loop.
As I'm not near my VS now I can't try this magic out for myself, but you might want to check Phil's article if you get stuck.
not sure exactly what you are looking for:
it seems you are missing a question table:
question
---------
question_id
question_text
then link that to the user
user_question
--------------
user_id
question_id
answer
The error is that
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(0).UserQuestion)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions.ElementAt(1).UserQuestion)%>
Generates HTML code:
<input id="UserQuestion" name="UserQuestion" type="text" value="UserQuestion" />
<input id="UserQuestion" name="UserQuestion" type="text" value="UserQuestion" />
As you can see: there are inputs with same id
s, which is forbidden. So when you post data back to the controller only one value is sent via PostParameters: UserQuestion=, no indexes, no prefixes, no UserQuestions.UserQuestion[0]
.
For more digging into alike question, I suggest using Fiddler and intercept traffic sent by your forms.
Second problem with your code is that you are using UpdateModel(User, "UserInfo")
and UserInfo parameter (of type User). (BTW: how does this code compiles? By all means it shouldn't).
It's better to use FormCollection
as parameter when you call UpdateModel
. Because in your case variable UserInfo
is already updated.
As for me, you are doing odd things, trying to edit whole collection.
Replace the code as such:
<h2>Question Creation</h2>
<% for (int i = 0; i < Model.UserInfo.UserQuestions.Count; i++) { %>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions[i].UserQuestion)%>
<%: Html.TextBoxFor(model => model.UserInfo.UserQuestions[i].UserAnswer)%>
<% } %>
then at least your code is dry.
[HttpPost] public void ChooseQuestion(User UserInfo) { IUserRepository repUser = new UserRepository(EntityFactory.GetEntity()); User usr = repUser.GetUserByID(Convert.ToInt32(Session["UserID"]));
UpdateModel(usr);
EntityFactory.GetEntity().SaveChanges();
}
depending on if questions exist or not this should work.
the UserInfo object should contain your questions, you could foreach
them and add them manualy as well.
It looks like you are running SaveChanges on a new entity that does not contain any changes rarther than one that contains the information updated by the client.
精彩评论