我正在构建一个具有以下实体的应用程序。
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 来限制回报,但我有点不知道应该如何去做。
如有任何帮助,我们将不胜感激!
我认为我需要利用 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();