linq C# Web Api剩余链接查询返回太多数据

xoefb8l8  于 2022-12-06  发布在  C#
关注(0)|答案(2)|浏览(107)

日安,我在返回DTO对象时遇到了问题。我有这些类

public class ProductBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public IEnumerable<ProductVariant> Variants { get; set; }
    public int BaseImageId { get; set; } = 0;

}

public class ProductVariant
{
    public int Id { get; set; }
    public int Quantity { get; set; }
    public int ProductBaseId { get; set; }
    public ProductBase productBase { get; set; }
    public int ProductSizeId { get; set; }
    public ProductSize ProductSize { get; set; }
    public int ProductColorId { get; set; }
    public ProductColor ProductColor { get; set; }

    public IEnumerable<ImageVariant> imageVariants { get; set; }
}

public class ProductColor
{
    public int Id { get; set; }
    public string Color { get; set; }
    public IEnumerable<ProductVariant> productVariant { get; set; }
}

public class ProductSize
{
    public int Id { get; set; }
    public string Size { get; set; }

    public IEnumerable<ProductVariant> productVariant { get; set; }
}

在productBaseRepository中,我有这样一个调用

public async Task<IEnumerable<Models.ProductBase>> GetAllWithVariantsAsync()
    {
        var result = await _dataContext.ProductBases
            .Include(pb => pb.Variants)
            .ThenInclude(v => v.ProductSize)
            .Include(pb => pb.Variants)
            .ThenInclude(v => v.ProductColor)
            .ToListAsync();

        return result;
    }

我已创建DTO转换函数

public static IEnumerable<ProductBaseDTO> ConvertToDto(this IEnumerable<ProductBase> productBases)
    {
        var returnProductBaseDto = (from product in productBases
                                    select new ProductBaseDTO
                                    {
                                        Id = product.Id,
                                        Name = product.Name,
                                        Variants = product.Variants.ToList(),
                                        Description = product.Description,
                                        BaseImageId = product.BaseImageId,
                                        
                                    }).ToList();
        
        return returnProductBaseDto;
    }

但是我把这个函数从swagger

[HttpGet]
    public async Task<ActionResult<List<ProductBaseDTO>>> GetAllProductsWithVariants()
    {
        var baseProductDomain = await _productBaseRepository.GetAllWithVariantsAsync();
        var baseProduct = baseProductDomain.ConvertToDto();
        return Ok(baseProduct);
    }

我得到了系统.文本.Json. json异常:检测到可能的对象循环。这可能是由于循环或对象深度大于允许的最大深度32
如果我从调用中删除变量,它就可以工作,所以我需要知道如何从变量中删除不必要值

uwopmtnx

uwopmtnx1#

出现这个问题是因为ProductVariant引用了ProductSizeProductColorProductSizeProductColor引用了一系列ProductVariant对象,而ProductVariant引用了它的BaseProduct,这就形成了一个循环,两个对象相互引用。
要解决此问题,请从ProductSizeProductColor中删除productVariant列表,或者从ProductVariant中删除ProductSizeProductColor引用。还要从ProductVariant中删除productBase引用。
如果需要,使用ID查找对象引用,而不是使用循环对象引用。
请参阅prevent property from being serialized in web API,了解如何在不从类中移除属性声明的情况下防止属性被序列化。

amrnrhlw

amrnrhlw2#

这是因为Variants有一个对其父类型的引用,您可以简单地将其设置为null,例如:
foreach(var x in baseProduct.SelectMany(c => c.Variants) { x.ProductBase = null }
我们通常使用不同的视图模型来停止这些循环,例如:

public class Order {
  public List<OrderLine> OrderLines {get;set}
}

public class OrderLine {
  public Order Order {get;set}
}

// Gets mapped to the following viewmodels:

public class OrderViewModel {
  public List<OrderOrderLineViewModel > OrderLines {get;set}
}

public class OrderOrderLineViewModel {
  public Order Order => null; // Stop object cycling
}

请注意,例外状况消息应该会告诉您问题所在,例如$.Variants.productBase.variants.productBase.variants或类似的消息。

相关问题