1

My DAL is based on Entity Framework Code First.

I have a post model and a tag model. One post can have several posts attached.

Here is my post:

public class Post 
{
    [Key]
    public int PostID { get; set; }
    ...
    public virtual ICollection<Tag> Tags { get; set; }
}

Here is my tag:

public class Tag
{
    [Key]
    public int TagID { get; set; }

    [Required, StringLength(50)]
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

When I save my post, I don't have any errors but nothing is saved in the DB.

enter image description here

As you can see on the screenshot above the TagID is 0 and I don't know why???

enter image description here

Any idea? Suggestions?

My tables are correctly created in Sql Server.

Thanks.

PS: My code must be ok because I copy/paste it from another location (where it works).


UPDATE

Here is the code to update tag entities (under a specific post)

    Tag t = m_TagRepository.GetTag(tag.Trim().ToUpper());
    if (t == null) t = new Tag { Name = tag.Trim().ToUpper() };
    post.Tags.Add(t);

Here is the code to save changes to a post (and tag below)

    public void SavePost(Post post)
    {
        if (post.PostID == 0)
        {
            m_Context.Posts.Add(post);
        }
        else
        {
            var entry = m_Context.Entry(post);
            entry.State = EntityState.Modified;
        }            
        m_Context.SaveChanges();
    }

I get the post back from the Edit view page:

    [Authorize, HttpPost, ValidateInput(false), Theme("Admin")]
    public ActionResult Edit(PostFullViewModel postToEdit)
    {
        if (!ModelState.IsValid)
            return View();

        Post post = Mapper.Map<PostFullViewModel, Post>(postToEdit);
        m_PostBusiness.UpdateTags(post, postToEdit.TagString);
        m_PostBusiness.SavePost(post);
        TempData.SetStatusMessage(Strings.Post_SavedSuccessfully);

        return RedirectToAction("Manage");
    }
6
  • 1
    Show us the code that creates the entities and adds them to the Context. Commented Jan 25, 2012 at 18:56
  • I updated my question to show the code. Thanks. Commented Jan 25, 2012 at 19:06
  • You still didn't show how did you get the post? Commented Jan 25, 2012 at 19:27
  • Sorry, I updated my question again. Commented Jan 25, 2012 at 20:16
  • Which exactly post can't be saved - new one or existing one? Or both? (Unfortunately I cannot see the images) Commented Jan 25, 2012 at 20:24

2 Answers 2

1

It is common problem asked many times. You got your post view model from HTTP request and mapped it to your post entity but the entity was created outside of EF context. You than added some tag to this unattached post, attached the post and change the state of the post to modified.

Now where is the problem? The problem is in EF state model. Each entity and each independent association has its own state. Changing post to modified has only said to EF that post was updated but the tag and relation between tag and post remains unchanged. Because of that EF will save only post.

The simple solution for specific case is doing this:

var post = GetPostFromYourRequest();
context.Posts.Attach(post);
ProcessTags(post, postToEdit);
context.SaveChanges();

The whole complicated logic is in process tags. Here it depends on what you want to do. If you only want to create new tags you will do what you did now (you must load existing tag from database with the same context you used for attaching post).

If you want to do any complex operation you should load original post with all tags from database and merge your incoming view model to original state. For example removing relation between existing post and tags is very hard to do without having current state from database loaded again. Detailed explanation of the problem is here.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, it works. Your explanations was very helpful.
0
  1. Figure out why TagID is 0 - WHen TagID is 0, you don't set the state as modified so nothing is saved.
  2. Fire up the SQL profiler to see what's happening on the SQL side (probably nothing because of 1)
  3. Go through Tom's excellent EF/MVC tutorial

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.