关于c#:如何在Entity Framework Core中配置多对多关系

How to configure a Many To Many relationship in Entity Framework Core

我有一些文章和一些作者,并希望将它们链接为:

  • 任何文章都可以有任意数量的作者,并且
  • 每个作者可以写任意数量的文章

我使用此教程创建了ManyToMany关系:https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration

这是我定义班级的方式。

文章

1
2
3
4
5
6
7
8
9
10
11
12
public class Article
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Title { get; set; }

    public DateTime Date { get; set; }

    public ICollection<ArticleAuthor> ArticleAuthors { get; set; }
}

作者

1
2
3
4
5
6
7
8
9
10
11
12
public class Author
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Column(TypeName ="text")] public string Name { get; set; }

    [Column(TypeName ="text")] public string Email { get; set; }

    public ICollection<ArticleAuthor> ArticleAuthors { get; set; }
}

ArticleAuthor

1
2
3
4
5
6
7
8
9
10
public class ArticleAuthor
{
    public int ArticleId { get; set; }

    public Article Article { get; set; }

    public int AuthorId { get; set; }

    public Author Author { get; set; }
}

DbContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<Article> Articles { get; set; }

    public DbSet<Author> Authors { get; set; }

    public DbSet<ArticleAuthor> ArticleAuthors { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ArticleAuthor>()
            .HasKey(bc => new {bc.ArticleId, bc.AuthorId});
        modelBuilder.Entity<ArticleAuthor>()
            .HasOne(bc => bc.Article)
            .WithMany(b => b.ArticleAuthors)
            .HasForeignKey(bc => bc.ArticleId);
        modelBuilder.Entity<ArticleAuthor>()
            .HasOne(bc => bc.Author)
            .WithMany(c => c.ArticleAuthors)
            .HasForeignKey(bc => bc.AuthorId);
    }
}

在我运行dotnet ef数据库更新后,将按预期创建表。

一切似乎都很好,除了当我尝试通过此服务与作者添加文章时:

服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// POST: api/Articles
[HttpPost]
public async Task<IActionResult> PostArticle([FromBody] Article article)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _context.Articles.Add(article);
    await _context.SaveChangesAsync();

    return Ok(article);
}

JSON

1
2
3
4
5
6
7
8
9
10
11
{
   "Title":"Title 2",
   "ReadingTime" : 2,
   "Date":"01.12.2019",
   "Theme":"1",
   "ArticleAuthors":[
        {
           "ID":"1"
        }
    ]
}

当我尝试与作者添加文章时,我一直被这个错误困扰

System.InvalidOperationException: The property 'AuthorId' on entity type 'ArticleAuthor' has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.


尝试此有效负载,应要求有ArticleId和AuthorId,ArticleId在父类中是隐式的,因此您至少应提供AuthorId:

1
2
3
4
5
6
7
8
9
10
11
{
   "Title":"Title 2",
   "ReadingTime" : 2,
   "Date":"01.12.2019",
   "Theme":"1",
   "ArticleAuthors":[
        {
           "AuthorId":"1"
        }
    ]
}