控制器内的 Linq 查询返回一个包含大量不需要的重复数据的数组

Linq query inside controller is returning an array with a lot of undesired duplicated data

我对控制器如何返回结果有一个不寻常的问题。

我正在为我的项目使用 .Net Core Entity Framework 和 SQL 服务器。

返回的数据是 AuthorList table 中的一个 Author 行和 AuthorBooks table 中的 3 个 Book 行。

这些书有一个 authorId,将它们链接到 AuthorList table。

在SQL我只是做了一个SELECT * FROM AuthorBooks WHERE authorId = 'author_33'

还有 returns AuthorBooks 中的 3 行书籍。

但是返回的 JSON 并不是我所需要的。

它列出了一个数组,每本书都有一个作者数组。所以它复制了很多数据,像这样:

[
    {
        "bookId": "1a",
        "authorId": "author_33",
        "bookText": "English_Variant1",
        "author": {
            "authorId": "author_33",
            "authorText": "Bio Book 102",
            "authorBooks": [
                {
                    "bookId": "4a",
                    "authorId": "author_33",
                    "bookText": "English",
                },
                {
                    "bookId": "9a",
                    "authorId": "author_33",
                    "bookText": "Spanish",
                }
            ]
        }
    },
    {
        "bookId": "4a",
        "authorId": "author_33",
        "bookText": "English",
        "author": {
            "authorId": "author_33",
            "authorText": "Bio Book 102",
            "authorBooks": [
                {
                    "bookId": "1a",
                    "authorId": "author_33",
                    "bookText": "English_Variant1",
                },
                {
                    "bookId": "9a",
                    "authorId": "author_33",
                    "bookText": "Spanish",
                }
            ]
        }
    },
    {
        "bookId": "9a",
        "authorId": "author_33",
        "bookText": "Spanish",
        "author": {
            "authorId": "author_33",
            "authorText": "Bio Book 102",
            "authorBooks": [
                {
                    "bookId": "1a",
                    "authorId": "author_33",
                    "bookText": "English_Variant1",
                },
                {
                    "bookId": "4a",
                    "authorId": "author_33",
                    "bookText": "English",
                }
            ]
        }
    }
]

但我需要它看起来像这样(注意它看起来好多了):

"author": {
"authorId": "author_33",
"authorText": "Bio Book 102",
"authorBooks": 
            [
                {
                "bookId": "1a",
                "authorId": "author_33",
                "bookText": "English_Variant1",
                },
                {
                    "bookId": "4a",
                    "authorId": "author_33",
                    "bookText": "English",
                },
                {
                    "bookId": "9a",
                    "authorId": "author_33",
                    "bookText": "Spanish",
                }
            ]
}

返回 JSON 数据的控制器相当简单:

[HttpGet("GetBooksByAuthorId/{id}")]
public async Task<ActionResult<IEnumerable<AuthorBooks>>> GetBooksByAuthorId(Guid id)
{
   var booksByAuthor = await _context.AuthorBooks.Where(q => q.AuthorId == id).ToListAsync();
   return booksByAuthor;
}

这是我的 AuthorBooks 模型:

public partial class AuthorBooks
{
    public Guid BookId { get; set; }
    public Guid? AuthorId { get; set; }
    public string BookText { get; set; }

    public virtual AuthorList Author { get; set; }
}

这是我的 AuthorList 模型:

public partial class AuthorList
{
    public Guid AuthorId { get; set; }
    public string AuthorText { get; set; }
    public virtual ICollection<AuthorBooks> AuthorBooks { get; set; }
}

在我的数据库上下文中,它们看起来像这样:

作者书籍:

modelBuilder.Entity<AuthorBooks>(entity =>
{
    entity.HasKey(e => e.BookId);

    entity.HasOne(d => d.Author)
        .WithMany(p => p.AuthorBooks)
        .HasForeignKey(d => d.AuthorId)
        .OnDelete(DeleteBehavior.Cascade)

    entity.ToTable("AuthorBooks");

    entity.Property(e => e.BookId)
        .HasColumnName("BookId");

    entity.Property(e => e.AuthorId)
        .HasColumnName("AuthorId");

    entity.Property(e => e.BookText)
        .HasColumnName("BookText");

});

作者名单:

modelBuilder.Entity<AuthorList>(entity =>
{
    entity.HasKey(e => e.AuthorId);
    entity.ToTable("AuthorList");

    entity.Property(e => e.AuthorId)
        .HasColumnName("AuthorId");

    entity.Property(e => e.AuthorText)
        .HasColumnName("AuthorText");
});

我认为这可能与我在模型中使用的 ICollections 有关。

但是当我删除它们时,我的数据库上下文出现错误 class。

所以我有点不知道该怎么做。

有没有办法格式化它,使其不会重复很多数据?

谢谢!

您似乎想要 return 根对象“AuthorList”,而不是“AuthorBooks”。根据您的上下文找到正确的作者,然后 return 改为它。

在您的控制器中,您可以查询包括相关书籍在内的作者,并相应地更改您的操作方法的 return 类型以反映查询结果的类型 -

[HttpGet("GetBooksByAuthorId/{id}")]
public async Task<ActionResult<AuthorList>> GetBooksByAuthorId(Guid id)
{
    var authorWithBooks = await _context.AuthorLists
                            .Include(p=> p.AuthorBooks)
                            .FirstOrDefaultAsync(p=> p.AuthorId == id);
    return authorWithBooks;
}

这将符合您预期的 JSON 结果。