API 控制器调用的循环引用

问题描述 投票:0回答:1

我正在构建一个具有以下实体的应用程序。

namespace MusicManager.Shared.Entities
{
    public class Piece
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
        public Publisher? Publisher { get; set; }
        public int? PublisherId { get; set; }
        public List<Part>? Parts { get; set; } = new List<Part>();
    }
}

namespace MusicManager.Shared.Entities
{
    public class Publisher
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public List<Piece>? Pieces { get; set; } = new List<Piece>();
    }
}

我的控制器有以下方法。

public async Task<ServiceResponse<List<Piece>>> GetAllPieces(bool order)
{
    var response = new ServiceResponse<List<Piece>>
    {
        Data = (order) ?
        await _dataContext.Pieces
            .OrderBy(x => x.Title)
            .Include(x => x.Publisher)
            .ToListAsync() :
        await _dataContext.Pieces
            .Include(x => x.Publisher)
            .ToListAsync()
    };

    return response;
}

public async Task<ServiceResponse<List<Publisher>>> GetAllPublishers(bool order)
{
    var response = new ServiceResponse<List<Publisher>>
    {
        Data = (order) ?
        await _dataContext.Publishers
            .OrderBy(x => x.Name)
            .Include(x => x.Pieces)
            .ToListAsync() :
        await _dataContext.Publishers
            .Include(x => x.Pieces)
            .ToListAsync()
    };

    return response;
}

对所有 Pieces 运行 Get 调用会得到一个循环结果,该调用将获取发布者、发布者引用引用片段,如此反复。我认为我需要利用 DTO 来限制回报,但我有点不知道应该如何去做。

如有任何帮助,我们将不胜感激!

c# entity-framework-core relationship
1个回答
0
投票

我认为我需要利用 DTO 来限制回报,但我有点不知道应该如何去做。

是的,这是处理此类问题的常见方法。例如,您可以引入多个 DTO 并手动映射到它们:

public class PieceDto
{
    public int Id { get; set; }
    public string Title { get; set; } = string.Empty;
    public PublisherInfoDto Publisher { get; set; }
}

public class PublisherInfoDto
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    // no "reverse" property 
}

查询如下所示:

await _dataContext.Pieces
    .Select(p => new PieceDto
     {
         Id = p.Id, 
         // rest of "simple" props
         Publisher = new PublisherInfoDto
         {
            Id = p.Publisher.Id // ...
         }
     })
    .ToListAsync();

PublisherDto
+
PieceInfoDto
类似。

备注:

  • 您可以使用像AutoMapper这样的库及其可查询扩展来减少映射的输入

  • 手动映射到最终投影中的相同类也应该有效,因为 EF 不会跟踪此类投影,也不会执行关系修复。 IE。像这样的东西:

    await _dataContext.Pieces
        .Select(p => new Piece
        {
            Id = p.Id, 
            // rest of "simple" props
            Publisher = new Publisher
            {
                Id = p.Publisher.Id,
                Name = p.Publisher.Name 
                // do not fill the reference property
            }
        })
        .ToListAsync();
    
  • 另请查看避免或控制 Entity Framework Core 中的循环引用

© www.soinside.com 2019 - 2024. All rights reserved.