我正在Web api核心(netcoreapp2.1)项目中使用Microsoft.EntityFrameworkCore.Sqlite
(2.1.0),以便将Blog
和Article
条目写入(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);
}
这是Blog
和Article
的类定义:
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吗?除了我,还有什么其他方法?
答案 0 :(得分:2)
要结合BlogId
和Name
限制,您可以为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();