简体   繁体   English

在 Entity Framework Core 中添加与同一个表具有多个一对一关系的实体时出现堆栈溢出

[英]Stack overflow when adding an entity with multiple one-to-one relationship with the same table in Entity Framework Core

I have an issue when adding entities with multiple one-to-one relationship with the same table in Entity Framework Core.在 Entity Framework Core 中添加与同一个表具有多个一对一关系的实体时遇到问题。 Based on this question I have the following things:基于这个问题,我有以下几点:

public class Article
{
    public int Id { get; set; }
    public int? PreviousId { get; set; }
    public Article Previous { get; set; }
    public int? NextId { get; set; }
    public Article Next { get; set; }
}

In the OnModelCreating of the DbContext as I have:OnModelCreatingDbContext ,我有:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.HasDefaultSchema("ab");
    modelBuilder.ApplyConfiguration(new ArticleEntityTypeConfiguration());
}

public class ArticleEntityTypeConfiguration : IEntityTypeConfiguration<Article>
{
    public void Configure(EntityTypeBuilder<Article> builder)
    {
        builder.ToTable("Articles");

        builder.HasKey(table => table.Id);
        builder.Property(table => table.Id).ValueGeneratedOnAdd();

        builder.HasOne(table => table.Previous).WithOne().HasForeignKey<Article>(table => table.PreviousId);
        builder.HasOne(table => table.Next).WithOne().HasForeignKey<Article>(table => table.NextId);
    }
}

And when adding a new article I get a stack overflow error and the app crashes.添加新文章时,出现堆栈溢出错误,应用程序崩溃。 I add an article with the following code:我添加了一篇文章,代码如下:

public Task AddNewArticleAsync(Article article)
{
    var newArticle = new Article();

    article.Next = newArticle;
    newArticle.Previous = article;

    await _dbContext.Programs.AddAsync(article);
}

Do you know how can I avoid that error?你知道我怎样才能避免这个错误吗? Thanks!谢谢!

if you add a new article,the PreviousId/NextId should be null or an existing Article.Id .If your Artice.Id is increasing, the previousId is the max id of the existing records.如果你添加一个新的文章,该PreviousId/NextId应该是空的或现有的Article.Id 。如果你Artice.Id增大时,previousId是现有记录最大ID。

Below is a demo to save new articles:以下是保存新文章的演示:

[HttpPost]
public async Task<IActionResult> Create(Article article)
{
    if (ModelState.IsValid)
    {
        int minArticleId = _context.Articles.Max(a => a.Id);
        var previous = await _context.Articles.Where(s => s.Id == minArticleId).FirstOrDefaultAsync();
        article.PreviousId = minArticleId;
        _context.Add(article);
        await _context.SaveChangesAsync();

        previous.NextId = article.Id;          
        _context.Update(previous);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    return View(article);
}

So I continue investigating about this and found this answer which helped me to fix the issue.所以,我继续调查这件事,发现这个答案,帮我解决这个问题。 The trick was to change the OnModelCreating of the DbContext to:诀窍是将OnModelCreatingDbContext为:

public void Configure(EntityTypeBuilder<Article> builder)
{
    builder.ToTable("Articles");

    builder.HasKey(table => table.Id);
    builder.Property(table => table.Id).ValueGeneratedOnAdd();

    builder
        .HasOne(table => table.Previous)
        .WithOne() // <-- one of this must be empty
        .HasForeignKey<Article>(table => table.PreviousId)
        .OnDelete(DeleteBehavior.Restrict);

    builder
        .HasOne(table => table.Next)
        .WithOne(table => table.Previous)
        .HasForeignKey<Article>(table => table.NextId);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM