实体框架代码优先:按ID添加多对多关系

时间:2011-09-19 23:43:46

标签: entity-framework ef-code-first

我有像这样定义的多对多关系:

public class Post
{
   //NOT SHOWN: Other properties
   public virtual ICollection<Tag> Tags { get; set; }
}

我看到的所有例子都会增加这样的多对多关系:

//Get the tag with ID of 1
var tag = context.Tags.Find(1);
// associate tag with ID of 1 with myPost
myPost.Tags.Add(tag);

但是,如果我只知道要与帖子关联的标签的ID,这似乎很乏味/效率低下。

理想情况下,我只想在我的Post实体上公开List<int> TagIds并能够通过将Tag Ids添加到列表中来添加标签,但我无法确定是否可以使用EF代码优先。

结论:在我想要关联的实体的ID中,将项目添加到多对多关系的最佳方法是什么。 (例如,如果我有一个标签ID列表,那么将这些标签与帖子联系起来的最佳方式是什么?)

3 个答案:

答案 0 :(得分:45)

使用这样的代码:

// Existing post without loading it from the database
var myPost = new Post() { Id = ... };
context.Posts.Attach(post);

// For each id of existing tag 
foreach (int tagId in someExistingTagIds)
{
    var tag = new Tag() { Id = tagId };
    context.Tags.Attach(tag);

    // Make a new relation
    post.Tags.Add(tag);
}

context.SaveChanges();

这将允许您在现有实体上创建M-N关系,而无需从数据库中加载任何内容。您只需要知道现有实体的ID。

答案 1 :(得分:1)

希望在EF中拥有更多专业知识的人能够帮助你,但如果是我在这种情况下,我会自己模拟M-M关系(因此,建模链接表)。这样,你可以拥有

myPost.PostTags.Add(new PostTagLink(){
  TagID = 1
});

但是现在你必须处理额外的链接表对象。另一方面,如果您要为关系添加更多属性,则无论如何都必须这样做。

如果有更好的解决方法,我也想知道。

答案 2 :(得分:0)

你为什么说它效率低下。如果您将其声明为虚拟,则在启用延迟加载后访问它时才会加载。如果您有Id值列表,请说明。然后,当您要加载所有列表时,需要为所有值调用getById。这比使用延迟加载效率低得多。

相关问题