在实体框架中添加具有多对多关系的项目

本文关键字:关系 项目 实体 框架 添加 | 更新日期: 2023-09-27 18:03:35

当我试图添加一个具有多对多关系的项目时,我得到一个主键冲突错误:

我有两个类-文章和标签,它们具有多对多关系:

public class Article
{
    public int ID { get; set; }
    public string Text { get; set; }
    public   ICollection<Tag>  Tags { get; set; }
}
public class Tag
{ 
    [Key]
    public string UrlSlug { get; set; }
    public string Name { get; set; }
    public ICollection<Article> Articles{ get; set; }
}

当我添加一个新的文章时,我允许用户输入任何标签,然后我想创建一个新的标签,如果标签还没有在数据库中创建,或者如果标签已经存在,我想将标签添加到文章对象的标签集合中。

因此,当我创建新的Article对象时,我调用以下函数:

public static Tag GetOrLoadTag(String tagStr)
{
    string tagUrl = Tag.CreateTagUrl(tagStr);
    var db = new SnippetContext();
    var tagFromDb = from tagdummy in db.Tags.Include(x => x.Articles)
                    where tagdummy.UrlSlug == tagUrl
                    select tagdummy;
    if (tagFromDb.FirstOrDefault() != null)
    { return tagFromDb.FirstOrDefault(); }
    else
    {
        //create and send back a new Tag
    }
}

这个函数基本上检查数据库中是否有可用的标签,如果有,则返回该标签,然后使用Article . tags . add()将该标签添加到Article对象的标签集合中。

然而,当我试图用下面的代码保存它时,我得到了一个违反PRIMARY KEY约束的错误

 db.Entry(article).State = EntityState.Modified;
 db.SaveChanges();

我不知道如何在文章和已经存在的标签之间创建关系。

在实体框架中添加具有多对多关系的项目

在整个操作过程中使用相同的上下文实例,您的工作将会轻松得多:

using (var ctx = new MyContext())
{
    Article article = ctx.Articles.Single(a => a.Id == articleId);
    Tag tag = ctx.Tags.SingleOrDefault(t => t.UrlSlug == tagUrl);
    if (tag == null) 
    {
       tag = new Tag() { ... }
       ctx.Tags.AddObject(tag);
    }
    article.Tags.Add(tag);
    ctx.SaveChanges();
}

如果你不想从数据库中加载文章(如果你知道文章存在,这个查询是多余的),你可以使用:

using (var ctx = new MyContext())
{
    Article article = new Article() { Id = articleId };
    ctx.Articles.Attach(article);
    Tag tag = ctx.Tags.SingleOrDefalut(t => t.UrlSlug == tagUrl);
    if (tag == null) 
    {
       tag = new Tag() { ... }
       ctx.Tags.AddObject(tag);
    }
    article.Tags.Add(tag);
    ctx.SaveChanges();
}

如何创建新标签?以及如何将现有的或创建的实体附加到文章上。

使用像

这样的字符
Article a = new Article(...);
a.tags.add(GetOrLoadTag("some tag"));

阅读本文http://thedatafarm.com/blog/data-access/inserting-many-to-many-relationships-in-ef-with-or-without-a-join-entity/