在实体框架中添加具有多对多关系的项目
本文关键字:关系 项目 实体 框架 添加 | 更新日期: 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/