数据库中没有保存数据,也没有触发错误

时间:2012-01-25 18:49:33

标签: asp.net-mvc entity-framework-4

我的DAL基于实体框架代码优先。

我有一个帖子模型和一个标签模型。一个帖子可以附上几个帖子。

这是我的帖子:

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

这是我的标签:

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

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

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

当我保存帖子时,我没有任何错误,但数据库中没有保存任何内容。

enter image description here

正如您在上面的屏幕截图中看到的,TagID为0,我不知道为什么???

enter image description here

有什么想法吗?建议?

我的表在Sql Server中正确创建。

感谢。

PS:我的代码必须正常,因为我从其他位置(工作地点)复制/粘贴它。


更新

以下是更新标记实体的代码(在特定帖子下)

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

以下是保存对帖子(以及下方标签)的更改的代码

    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();
    }

我从编辑视图页面返回了帖子:

    [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");
    }

2 个答案:

答案 0 :(得分:1)

这是多次被问到的常见问题。您从HTTP请求获得了您的帖子视图模型,并将其映射到您的帖子实体,但该实体是在EF上下文之外创建的。您只需在此未附加的帖子中添加一些标记,附加帖子并将帖子的状态更改为已修改。

现在问题出在哪里?问题出在EF状态模型中。每个实体和每个independent association都有自己的状态。将帖子更改为修改后只对EF说帖子已更新,但标签和帖子之间的标签和关系保持不变。因为EF只保存帖子。

针对特定案例的简单解决方案是:

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

整个复杂的逻辑是在过程标签中。这取决于你想做什么。如果您只想创建新标记,您将执行您现在所做的操作(必须使用与附加帖子相同的上下文从数据库加载现有标记)。

如果要执行任何复杂操作,则应使用数据库中的所有标记加载原始帖子,并将传入视图模型合并到原始状态。例如,如果没有再次加载数据库的当前状态,则很难删除现有帖子和标签之间的关系。问题的详细解释是here

答案 1 :(得分:0)

  1. 找出TagID为0的原因 - 当TagID为0时,您不会将状态设置为已修改,因此不会保存任何内容。
  2. 启动SQL分析器以查看SQL端发生了什么(可能因为1而没有)
  3. 通过Tom的优秀EF/MVC tutorial