C# 多次引用数据库项时将其删除

C# 多次引用数据库项时将其删除,c#,asp.net-mvc-4,C#,Asp.net Mvc 4,我正在创建一个简单的博客应用程序来下载.NETMVC4,我遇到了一个问题。除了我尝试为每个博客使用字符串数组标记博客外,其他一切都正常,如下所示: public class BlogEntry { public List<Comment> BlogComments { get; set; } public virtual List<String> RawTags { get; set; } public virtu

我正在创建一个简单的博客应用程序来下载.NETMVC4,我遇到了一个问题。除了我尝试为每个博客使用字符串数组标记博客外,其他一切都正常,如下所示:

 public class BlogEntry
    {
        public List<Comment> BlogComments { get; set; }
        public virtual List<String> RawTags { get; set; }
        public virtual List<Tag> BlogTags { get; set; }
        public virtual User Author { get; set; }
        public int AuthorId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public DateTime DatePosted { get; set; }

        [Key]
        public int Id { get; set; }

        public bool IsAcceptingComments { get; set; }
        public bool IsVisible { get; set; }
        public DateTime LastEdited { get; set; }

    }

 public class Tag
    {
         [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public int RefCount { get; set; }
    }
公共类博客条目
{
公共列表BlogComments{get;set;}
公共虚拟列表RawTags{get;set;}
公共虚拟列表BlogTags{get;set;}
公共虚拟用户作者{get;set;}
公共int AuthorId{get;set;}
公共字符串标题{get;set;}
公共字符串内容{get;set;}
public DateTime DatePosted{get;set;}
[关键]
公共int Id{get;set;}
公共bool IsAcceptingComments{get;set;}
公共布尔值可见{get;set;}
公共日期时间上次编辑{get;set;}
}
公共类标签
{
[关键]
公共int Id{get;set;}
公共字符串名称{get;set;}
公共int RefCount{get;set;}
}
创建博客并对其进行标记后,我使用以下方法将标记保存到博客条目模型中:

 [HttpPost]
        public int Create(string data)
        {
            if (data != null)
            {
                BlogEntry newBlog = JsonConvert.DeserializeObject<BlogEntry>(data);

                newBlog.Author = Session["user"] as User;
                newBlog.AuthorId = newBlog.Author.Id;
                newBlog.IsVisible = true;
                newBlog.IsAcceptingComments = true;
                newBlog.LastEdited = DateTime.Now;
                newBlog.DatePosted = DateTime.Now;
                newBlog.BlogTags = new List<Tag>();

                foreach (String s in newBlog.RawTags)
                {
                    // First check to see if the tag already exists
                    Tag check = Db.Tags.Where(m => m.Name == s).FirstOrDefault();
                    if (check != null)
                    {
                        check.RefCount++;
                        newBlog.BlogTags.Add(check);
                        Db.Tags.Attach(check);
                        Db.Entry(check).State = System.Data.Entity.EntityState.Modified;
                        Db.SaveChanges();
                    }
                    else
                    {
                        // Create a new tag
                        Tag newTag = new Tag();
                        newTag.Name = s;
                        newTag.RefCount = 1;
                        newBlog.BlogTags.Add(newTag);
                        Db.Tags.Add(newTag);
                    }
                }

                Db.BlogEntries.Add(newBlog);
                Db.SaveChanges();

                return newBlog.Id;
            }

            return -1;
        }
[HttpPost]
公共整数创建(字符串数据)
{
如果(数据!=null)
{
BlogEntry newBlog=JsonConvert.DeserializeObject(数据);
newBlog.Author=会话[“用户”]作为用户;
newBlog.AuthorId=newBlog.Author.Id;
newBlog.IsVisible=true;
newBlog.IsAcceptingComments=true;
newBlog.lastdedited=DateTime.Now;
newBlog.DatePosted=DateTime.Now;
newBlog.BlogTags=新列表();
foreach(newBlog.RawTags中的字符串s)
{
//首先检查标记是否已经存在
tagcheck=Db.Tags.Where(m=>m.Name==s.FirstOrDefault();
如果(检查!=null)
{
check.RefCount++;
newBlog.BlogTags.Add(检查);
Db.标签。附加(检查);
Db.Entry(check).State=System.Data.Entity.EntityState.Modified;
Db.SaveChanges();
}
其他的
{
//创建一个新标记
标签newTag=新标签();
newTag.Name=s;
newTag.RefCount=1;
newBlog.BlogTags.Add(newTag);
Db.Tags.Add(newTag);
}
}
添加(newBlog);
Db.SaveChanges();
返回newBlog.Id;
}
返回-1;
}

首先,我检查一下标签是否已经存在。。如果是这样,我会尝试向newBlog对象添加相同的标记,
check
。我本以为这只会在DbSet中保存对该标记对象的引用,但是,如果我创建多个带有标记“html”的博客文章,然后运行查询查看哪些博客具有html标记,则只有最近标记的博客保留此值。。。。我该怎么做才能让数据库中有多个BlogEntry对象和同一个标记对象?

我现在没有我的开发机器,所以这只是一个猜测,但我想这比让你等到明天要好

我不认为您需要
if(check!=null)
中的最后3行,事实上,我想知道它们是否把您搞砸了:

Db.Tags.Attach(check);
Db.Entry(check).State = System.Data.Entity.EntityState.Modified;
Db.SaveChanges();
您不需要附加,因为您已经从Db对象获得了它,所以应该已经在跟踪它了。这意味着您不需要更改状态,至于SaveChanges,您将在下面执行

现在还有另一个免责声明:我在Entity Framework(版本6,如果您想知道的话)上做了一些工作,但在MVC上没有做,所以可能会有所不同,但我的理解是,最好为每一组指令创建一个新的DbContext,而不是使用一个只跟踪运行中的更改的类变量。我不确定这是否是您正在做的事情,但从这个代码示例来看,情况是这样的。假设与MVC相关,可以考虑在CREATE方法的顶部创建一个新的DBWORDER(DB)。
让我知道它是如何运行的——如果这没有帮助,我将删除此答案。

首先,您必须更新
标记
类,以便它能够跟踪其注册的博客条目本身。在这里,
bloggentry
Tag
类具有
多对多
关系。因此,
标记
类如下所示:

public class Tag
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int RefCount { get; set; }
    public virtual List<BlogEntry> BlogEntries { get; set; } // MODIFICATION
}
要查看哪些博客具有
html
标记,您只需查询
标记
类,然后搜索
BlogEntries
即可获得所需的博客。祝你好运

foreach (String s in newBlog.RawTags)
{ 
    // First check to see if the tag already exists
    Tag check = Db.Tags.Where(m => m.Name == s).FirstOrDefault();
    if (check != null)
    {
        check.RefCount++;
        check.BlogEntries.Add(newBlog); // MODIFICATION
        newBlog.BlogTags.Add(check);
        Db.Tags.Attach(check);
        Db.Entry(check).State = System.Data.Entity.EntityState.Modified;
        Db.SaveChanges();
    }
    else
    {
        // Create a new tag
        Tag newTag = new Tag();
        newTag.Name = s;
        newTag.RefCount = 1;
        newTag.BlogEntries = new List<BlogEntry>(); // MODIFICATION
        newTag.BlogEntries.Add(newBlog); // MODIFICATION
        newBlog.BlogTags.Add(newTag);
        Db.Tags.Add(newTag);
    }
}