当我尝试添加具有多对多关系的项目时,我收到主键违规错误:
我有两个类 - 文章和标签有多对多的关系:
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
}
}
此函数基本上检查数据库中是否有可用的Tag,如果是,则返回该Tag,然后使用article.Tags.Add()将其添加到Article对象的Tag集合中。
但是,当我尝试使用以下代码保存时,我收到违反PRIMARY KEY约束错误
db.Entry(article).State = EntityState.Modified;
db.SaveChanges();
我无法弄清楚我应该如何在文章和现有标签之间建立关系。
答案 0 :(得分:17)
使用相同的上下文实例进行整个操作处理,您的生活将更加轻松:
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();
}
答案 1 :(得分:0)
您如何创建新标签?如何将现有或创建的实体附加到文章中。
使用类似
的内容Article a = new Article(...);
a.tags.add(GetOrLoadTag("some tag"));