一对多关系中的唯一名称

时间:2018-07-25 07:03:52

标签: c# asp.net-core relational-database entity-framework-core

我正在Web api核心(netcoreapp2.1)项目中使用Microsoft.EntityFrameworkCore.Sqlite(2.1.0),以便将BlogArticle条目写入(SQLite)数据库。他们之间存在一对多的关系,我正在这样的流利的api中实现这种关系。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Blog>().HasIndex(b => b.Name).IsUnique();
  modelBuilder.Entity<Blog>().HasMany(b => b.Articles).WithOne().OnDelete(DeleteBehavior.Cascade);
}

这是BlogArticle的类定义:

public class Blog
{
    [Required]
    public Guid BlogId { get; set; }
    [Required]
    public String    Name { get; set; }
    public String    Description { get; set; }
    public DateTime Created { get; set; }
    public List<Article> Articles { get; set; }

}

public class Article
{
    [Required]
    public Guid      ArticleId { get; set; }
    [Required]
    public Guid      BlogId   { get; set; }
    [Required]
    public String    Name { get; set; }
    public String    Description { get; set; }
    public DateTime  Created { get; set; }
    public String    Content { get; set; }

}

Article的下一个要求是在(“父”)Name中具有唯一的Blog。所以我不能像这样设置它:

modelBuilder.Entity<Article>().HasIndex(a => a.Name).IsUnique();

以上代码段将要求每篇文章在整个数据库中都具有唯一的Name。我想要的是对于(“ parent”)Name条目具有唯一的Blog

我想到的一个解决方案是在编写新的Article条目之前明确检查这种情况:

[HttpPost("{id}/articles")] // id - is the `Blog` id here
public IActionResult CreateArticle(Guid id, Article article)
{
  List<Article> articles = blogRepository.GetArticlesByBlogId(id);

  // Look up the names of all articles belonging to the affected `Blog`
  if (articles.Any(a => a.Name == article.Name))
  {
    return BadRequest("Article name is not unique!");
  }

  article.ArticleId = new Guid();
  article.BlogId = id;
  article.Created = DateTime.Now;

  blogRepository.AddArticle(article);
  blogRepository.SaveChanges();
  return CreatedAtRoute("GetArticle", new { id = article.ArticleId }, article);
}

我发现此实现并不十分优雅,我也很确定必须有另一种实现方法。可以使用流利的api吗?除了我,还有什么其他方法?

1 个答案:

答案 0 :(得分:2)

要结合BlogIdName限制,您可以为Index定义一个Article,如下所示:

        builder.Entity<Blog>().HasIndex(b => b.Name).IsUnique();
        builder.Entity<Blog>().HasMany(b => b.Articles).WithOne().OnDelete(DeleteBehavior.Cascade);
        builder.Entity<Article>().HasIndex(a => new { a.Name, a.BlogId }).IsUnique();