开发者

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 Controller

public 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 ids, 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.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜