EF代码优先:插入多对多

时间:2012-07-18 23:18:11

标签: c# entity-framework ef-code-first

帖子可以有很多主题。可以将主题分配给许多帖子。 添加从主题列表中选择的两个主题的帖子时,两个NULL主题也会插入到我的主题表中。请参阅Id=3435。我做错了什么?不应该改变主题。我正在添加一个新帖子并从固定数量的主题中选择主题(下拉列表)。它在PostTopics表(PostID,TopicID)中被跟踪。

主题表:

Id    TopicName   TopicDesc       
31    Sports  Sports  
32    Game    Game    
33    Politics    Politics    
34    NULL    NULL    
35    NULL    NULL

TopicPosts表:

Topic_Id    Post_Id
34  11
35  11


public class Post
{
    public int Id { get; set; }
    public int UserId { get; set; }

    public virtual ICollection<Topic> PostTopics { get; set; }

}


public class Topic
{
    public int Id { get; set; }
    public string TopicName { get; set; }

    public virtual ICollection<Request> Requests { get; set; }

}

// insert code: I think the problem is here

  using (var context = new ChatContext())
  {
             // Post
             context.Posts.Add(pobjPost);

             pobjPost.PostTopics = new List<Topic>();
             // topics
             foreach (var i in pobjTopics)
             {

             pobjPost.PostTopics.Add(i);
             }

             context.SaveChanges();
   }

2 个答案:

答案 0 :(得分:3)

您必须首先将主题附加到上下文,以将它们置于状态Unchanged,并告诉EF它们已存在于数据库中。否则,EF将假定主题是新主题并将其插入数据库。之后,您可以将帖子添加到上下文中,以便可以将帖子作为新实体与多对多连接表中的关系记录一起插入到数据库中:

using (var context = new ChatContext())
{
    pobjPost.PostTopics = new List<Topic>();
    foreach (var pobjTopic in pobjTopics)
    {
        context.Topics.Attach(pobjTopic); // topic is in state Unchanged now
        pobjPost.PostTopics.Add(pobjTopic);
    }
    context.Posts.Add(pobjPost); // post in state Added, topics still Unchanged
    context.SaveChanges();
}

答案 1 :(得分:0)

要创建关系,首先应将两个相关对象附加到上下文中。

尝试这种方式:

using (var context = new ChatContext())
      {
                 // Post
                 context.Posts.Attach(pobjPost);

                 pobjPost.PostTopics = new List<Topic>();
                 // topics
                 foreach (var i in pobjTopics)
                 {

                 pobjPost.PostTopics.Add(i);
                 }