如何更新/ MVC中创造了许多一对多关系数据代码首先使用EF?(How to update/crea

2019-07-30 07:37发布

我经历的StackOverflow,谷歌和asp.net钻研试图找到一个明确的,如何做到这一点简单的例子。 所有的例子已不适用的抽象或参与的并发症。 我一直无法从中提取了许多有益的。 到目前为止,他们都没有完全回答我的问题或解决了我的问题(一个或多个)。

我的工作有以下型号的MVC项目:

Article.cs:

public class Article
{

    public int ArticleId { get; set; }
    public string Title { get; set; }
    .
    .
    .
    public virtual ICollection<Category> Categories { get; set; }

    public Article()
    {
        Categories = new HashSet<Category>();
    }
}

Category.cs:

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Article> Articles { get; set; }

    public Category()
    {
        Articles = new HashSet<Article>();
    }
}

ArticleEntities.cs:

public class ArticleEntities : DbContext
{
    public DbSet<Article> Articles { get; set; }
    public DbSet<Category> Categories { get; set; }

}

文章可以有很多种类和类别可以属于很多文章。

到目前为止,我可以保存/更新/创建除类别中的所有项目的字段。

我代表他们作为视图中的复选框。 我可以为选定的复选框的值到控制器,但是,我已经将它们存储在数据库与文章已经失败每一次尝试。

我如何能:

1)当保存编辑后的文章,更新的关系表中的现有关系,而无需创建重复?

2)当保存一个新的文章,请在关系表中选择的关系?

Answer 1:

我假设你的列表CategoryId从控制器后动作S,一个List<int>或更一般只是一个IEnumerable<int>

1)当保存编辑后的文章,更新的关系表中的现有关系,而无需创建重复?

Article article; // from post action parameters
IEnumerable<int> categoryIds; // from post action parameters

using (var ctx = new MyDbContext())
{
    // Load original article from DB including its current categories
    var articleInDb = ctx.Articles.Include(a => a.Categories)
        .Single(a => a.ArticleId == article.ArticleId);

    // Update scalar properties of the article
    ctx.Entry(articleInDb).CurrentValues.SetValues(article);

    // Remove categories that are not in the id list anymore
    foreach (var categoryInDb in articleInDb.Categories.ToList())
    {
        if (!categoryIds.Contains(categoryInDb.CategoryId))
            articleInDb.Categories.Remove(categoryInDb);
    }

    // Add categories that are not in the DB list but in id list
    foreach (var categoryId in categoryIds)
    {
        if (!articleInDb.Categories.Any(c => c.CategoryId == categoryId))
        {
            var category = new Category { CategoryId = categoryId };
            ctx.Categories.Attach(category); // this avoids duplicate categories
            articleInDb.Categories.Add(category);
        }
    }

    ctx.SaveChanges();
}

需要注意的是,代码也可以当你有一个ArticleViewModel代替的Article ,因为属性名称是相同的( SetValues接受一个任意的object )。

2)当保存一个新的文章,请在关系表中选择的关系?

或多或少相同的思路之上,但简单,因为你并不需要在数据库中的原始状态进行比较:

Article article; // from post action parameters
IEnumerable<int> categoryIds; // from post action parameters

using (var ctx = new MyDbContext())
{
    foreach (var categoryId in categoryIds)
    {
        var category = new Category { CategoryId = categoryId };
        ctx.Categories.Attach(category); // this avoids duplicate categories
        article.Categories.Add(category);
        // I assume here that article.Categories was empty before
    }
    ctx.Articles.Add(article);

    ctx.SaveChanges();
}


文章来源: How to update/create many-to-many relational data in MVC Code-first using EF?