【问题标题】:Entity framework 4 many-to-many insertion?实体框架4多对多插入?
【发布时间】:2011-06-02 01:17:47
【问题描述】:

我对使用 Entity Framework 4,POCO 的多对多插入过程不是很熟悉。我有一个包含 3 个表的博客:帖子、评论和标签。一个帖子可以有很多标签,一个标签可以在很多帖子中。以下是 PostTag 模型:

public class Tag
{
    public int Id { get; set; }

    [Required]
    [StringLength(25, ErrorMessage = "Tag name can't exceed 25 characters.")]
    public string Name { get; set; }

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

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

    [Required]
    [StringLength(512, ErrorMessage = "Title can't exceed 512 characters")]
    public string Title { get; set; }

    [Required]
    [AllowHtml]
    public string Content { get; set; }

    public string FriendlyUrl { get; set; }
    public DateTime PostedDate { get; set; }
    public bool IsActive { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

现在,当我添加新帖子时,我不确定应该采取什么正确的做法。我在想我会有一个文本框,我可以在其中为该帖子选择多个标签(这部分已经完成),在我的控制器中,我将检查标签是否已经存在,如果不存在,那么我将插入新标签。但我什至不确定基于我为 EF 创建的模型,他们会创建一个 PostsTags 表,还是只创建一个标签和一个 Posts 表以及两者之间的链接?

如何插入新的 帖子 并将标签设置到该帖子?只是newPost.Tags = Tags(其中标签是被选中的,我什至需要检查它们是否已经存在?),然后是_post.Add(newPost);之类的东西?

谢谢。

【问题讨论】:

  • 嘿 Saxman,你在设置自定义初始化器吗? (DbDatabase.SetInitializer) 如果要更改模型,则应让 EF 也构建数据库,以便模型与数据库匹配。这可能是您的多对多无法正常工作的原因。如果您需要知道如何执行此操作,请告诉我!恕我直言,您真的不应该在域模型中定义查找实体。 EF 将为您完成这项工作并使其透明化。
  • 嗨,Paul,我确实将 EF 设置为 DropCreateDatabaseIfModelChanges,我将再次尝试您在另一篇文章中使用的方法,看看多对多关系是否有效。谢谢。

标签: asp.net-mvc entity-framework-4 persistence many-to-many


【解决方案1】:

我认为这就是你想要的。

var tag = context.Tags.FirstOrDefault(x=>x.Name == name);
if (tag == null)
    context.Tags.AddObject(tag = new Tag { Name = name });
if (!post.Tags.Contains(tag))
    post.Tags.Add(tag);

编码新年快乐))

【讨论】:

  • 在使用 tag 之前,直到第 4 行,您才对它进行空检查。因此,您有可能在第 2 行中获得 NullReferenceException
【解决方案2】:

我建议不要在数据库中维护多对多关系。

您应该考虑创建一个名为 PostTagPostTagLookup 之类的查找表。

这将包含两列 - PostIdTagId

正如@Moyo 在his answer 中提到的那样,实体框架可以出色地处理查找表:

Entity Framework 会将映射表转换为双方实体的集合,而表本身将基本上消失。

【讨论】:

  • 我有点困惑,你认为这比建立多对多关系更好吗?为了使用这种查找表方法,我需要对模型进行哪些更改?谢谢。
  • 这取决于你如何实现它。它可以像添加表格和更新您的解决方案一样简单。
  • 请注意:您应该只将两个实体 id 放入查找表(PostId、TagId)中,并省略额外的 Id 列。如果添加该 Id 列,EF 将不会按照参考答案中的描述“隐藏”查找表。
  • 我还需要包含 Post 和 Tag 模型吗?例如:public int PostId { get; set; } public virtual Post Post { get; set; } ?谢谢。
  • 对不起,我不太明白你问了什么。您无需在此处执行其他操作即可使其正常工作。
【解决方案3】:

如果没有查找表的 Id,我似乎无法使其工作,这就是我为使其工作所做的工作。可能不是最好和最有效的方法,但它正在工作:

public class PostTagLookup
{
    public int Id { get; set; }
    public int PostId { get; set; }
    public int TagId { get; set; }

    public virtual Post Post { get; set; }
    public virtual Tag Tag { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多