在实体框架中添加多对多关系的项目 [英] Adding Item with Many-to-Many Relationship In Entity Framework

查看:179
本文介绍了在实体框架中添加多对多关系的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试添加具有多对多关系的项目时遇到主键违规错误:



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

  public class Article 
{
public int ID {得到;组; }
public string Text {get;组; }
public ICollection< Tag>标签{get;组;
}

public class标签
{
[Key]
public string UrlSlug {get;组; }
public string Name {get;组; }
public ICollection< Article>文章{get;组; }
}

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



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

  public static Tag GetOrLoadTag(String tagStr)
{
string tagUrl = Tag.CreateTagUrl(tagStr);
var db = new SnippetContext();
var tagFromDb =来自db.Tags.Include(x => x.Articles)中的tagdummy
其中tagdummy.UrlSlug == tagUrl
select tagdummy;
if(tagFromDb.FirstOrDefault()!= null)
{return tagFromDb.FirstOrDefault(); }
else
{
//创建并发回一个新的标签
}

}
/ pre>

此函数基本上检查数据库中是否有可用的标签,如果是,则返回该标签,然后将其添加到Article对象的Tag集合中,使用文章.Tags.Add()。



但是,当我尝试使用下面的代码保存它时,我得到违反PRIMARY KEY约束错误

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

我无法弄清楚我应该如何创建文章和已经现有的标签。

解决方案

使用相同的上下文实例进行整个操作,您的生活将更容易: p>

  using(var ctx = new MyContext())
{
Article article = ctx.Articles.Single a => a.Id == articleId);
标签标签= 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);

标签标签= ctx.Tags.SingleOrDefalut(t => t.UrlSlug == tagUrl);
if(tag == null)
{
tag = new Tag(){...}
ctx.Tags.AddObject(tag);
}

article.Tags.Add(tag);
ctx.SaveChanges();
}


I am getting a primary key violation error when I attempt to add an item with a many-to-many relationship:

I have two classes - Articles and Tags which have a many-to-many relationship :

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; }
}

When I add a new Article I allow the user to input any Tags and then I want to create a new Tag if the Tag isn't created yet in the database or add the Tag to the Tags collection of the Article object if the Tag already exists.

Therefore when I am creating the new Article object I call the below function:

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
            }

        }

This function basically checks if there is an available Tag in the database and if so returns that Tag which is then added to the Tag collection of the Article object using article.Tags.Add().

However, when I attempt to save this using the below code I get a Violation of PRIMARY KEY constraint error

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

I can't figure out how I should go about just creating a relationship between the Article and the already existing Tag.

解决方案

Use the same context instance for the whole processing of your operation and your life will be much easier:

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();
}

If you don't want to load the article from database (that query is redundant if you know that article exists) you can use:

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();
}

这篇关于在实体框架中添加多对多关系的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆