ASP.net 检测到 6 个对象循环自动映射器嵌套列表
ASP.net 6 Object Cycle was detected automapper nested list
我目前正在做一个个人项目,当 [=19] =] 被击中。每次我使用 API/transaction
端点时都会收到此错误
System.Collections.Generic.List`1[ProjectName.Modules.Transaction.Core.DTO.GetAllTransactionRes]
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.TransactionId.
这是 UserTransaction
实体
public class UserTransaction
{
public int TransactionId { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<OrderedProduct> OrderedProducts { get; set; }
}
这是 Ordered Product
实体
public class OrderedProduct
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
public virtual UserTransaction UserTransaction { get; set; }
}
这是我的地图绘制器。 GetAllTransactionRes
和 AllOrderedProductDTO
是 UserTransaction
和 OrderedProduct
实体的精确副本。
CreateMap<UserTransaction, GetAllTransactionRes>().ForMember(s => s.OrderedProducts, c => c.MapFrom(m => m.OrderedProducts));
CreateMap<OrderedProduct, AllOrderedProductDTO>();
因为我在使用 MediatR。这是我的 GetAllTransactionQuery
的处理程序
public async Task<ICollection<GetAllTransactionRes>> Handle(GetAllTransactionQuery request, CancellationToken cancellationToken)
{
var Transactions = await _context.UserTransactions.Include(ut => ut.OrderedProducts).ToListAsync();
var mapped = _mapper.Map<ICollection<UserTransaction>, ICollection<GetAllTransactionRes>>(Transactions);
return mapped;
}
在使用 automapper 之前,我使用了 efcore
中的 .include
方法,这给了我同样的错误,我搜索了答案,一个人在 Whosebug 问题中评论说我不应该 return数据库实体直接在我的 API 中。
我做错了什么?谢谢
问题是您的 AllOrderedProductDTO
和 GetAllTransactionRes
数据传输对象有循环引用 - 交易包含产品,交易包含产品...
这是 DTO 类 我建议打破循环:
public class GetAllTransactionRes
{
public int TransactionId { get; set; }
public DateTime Date { get; set; }
// be sure to use the products DTO here and not the entity because the entity has the loop
public virtual ICollection<AllOrderedProductDTO> OrderedProducts { get; set; }
}
public class AllOrderedProductDTO
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
// do not include the transaction entity or DTO here so that we avoid the loop
//public virtual UserTransaction UserTransaction { get; set; }
}
我有类似的问题。我通过添加装饰来解决这个问题。
参考文档:https://docs.microsoft.com/en-us/ef/core/querying/related-data/serialization
public class OrderedProduct
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
[JsonIgnore]
public virtual UserTransaction UserTransaction { get; set; }
}
我目前正在做一个个人项目,当 [=19] =] 被击中。每次我使用 API/transaction
端点时都会收到此错误
System.Collections.Generic.List`1[ProjectName.Modules.Transaction.Core.DTO.GetAllTransactionRes]
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.OrderedProducts.UserTransaction.TransactionId.
这是 UserTransaction
实体
public class UserTransaction
{
public int TransactionId { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<OrderedProduct> OrderedProducts { get; set; }
}
这是 Ordered Product
实体
public class OrderedProduct
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
public virtual UserTransaction UserTransaction { get; set; }
}
这是我的地图绘制器。 GetAllTransactionRes
和 AllOrderedProductDTO
是 UserTransaction
和 OrderedProduct
实体的精确副本。
CreateMap<UserTransaction, GetAllTransactionRes>().ForMember(s => s.OrderedProducts, c => c.MapFrom(m => m.OrderedProducts));
CreateMap<OrderedProduct, AllOrderedProductDTO>();
因为我在使用 MediatR。这是我的 GetAllTransactionQuery
public async Task<ICollection<GetAllTransactionRes>> Handle(GetAllTransactionQuery request, CancellationToken cancellationToken)
{
var Transactions = await _context.UserTransactions.Include(ut => ut.OrderedProducts).ToListAsync();
var mapped = _mapper.Map<ICollection<UserTransaction>, ICollection<GetAllTransactionRes>>(Transactions);
return mapped;
}
在使用 automapper 之前,我使用了 efcore
中的 .include
方法,这给了我同样的错误,我搜索了答案,一个人在 Whosebug 问题中评论说我不应该 return数据库实体直接在我的 API 中。
我做错了什么?谢谢
问题是您的 AllOrderedProductDTO
和 GetAllTransactionRes
数据传输对象有循环引用 - 交易包含产品,交易包含产品...
这是 DTO 类 我建议打破循环:
public class GetAllTransactionRes
{
public int TransactionId { get; set; }
public DateTime Date { get; set; }
// be sure to use the products DTO here and not the entity because the entity has the loop
public virtual ICollection<AllOrderedProductDTO> OrderedProducts { get; set; }
}
public class AllOrderedProductDTO
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
// do not include the transaction entity or DTO here so that we avoid the loop
//public virtual UserTransaction UserTransaction { get; set; }
}
我有类似的问题。我通过添加装饰来解决这个问题。
参考文档:https://docs.microsoft.com/en-us/ef/core/querying/related-data/serialization
public class OrderedProduct
{
public int Id { get; set; }
public string Product { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool Returned { get; set; }
public int TransactionId { get; set; }
[JsonIgnore]
public virtual UserTransaction UserTransaction { get; set; }
}