多次引用数据库项时会被删除

时间:2014-02-25 01:41:17

标签: c# asp.net-mvc-4

我正在创建一个简单的博客应用程序来降低.NET MVC 4,我遇到了问题。除了当我尝试使用每个博客的字符串数组标记博客时,一切都有效:

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

创建博客并对其进行标记后,我使用以下标记将标记保存到BlogEntry模型中:

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

首先,我检查标签是否已经存在。如果存在,我尝试将相同的标签check添加到newBlog对象。我原以为这只会在DbSet中保存对这个Tag对象的引用,但是,如果我用标签“html”创建多个博客帖子,然后运行查询以查看哪些博客有html标签,只有最多最近标记的博客保留了这个值....我能做什么才能在数据库中拥有多个具有相同Tag对象的BlogEntry对象?

2 个答案:

答案 0 :(得分:0)

我现在面前没有我的开发机器,所以这只是猜测,但我认为这比让你等到明天更好......

我认为你不需要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方法的顶部创建一个新的DbContext(Db)。

让我知道它是怎么回事 - 如果这没有帮助,我会删除这个答案。

答案 1 :(得分:0)

首先,您必须更新Tag类,以便它可以跟踪其注册的博客条目。这里BlogEntryTag类的关系为many-to-many。所以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
}

现在,您必须将博客条目添加到其所有标记中以进行反向引用,以便以简单的方式满足您的查询。请查看我在下面for-loop中所做的修改:

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

要查看哪些博客包含html标记,您只需查询Tag类,然后搜索BlogEntries即可获得所需的博客。祝你好运!