简体   繁体   English

C# Web Api rest linq 查询返回太多数据

[英]C# Web Api rest linq query return too much data

Good day, I run into the problem then returning DTO object. I have these classes美好的一天,我遇到问题然后返回 DTO object。我有这些课程

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; }
}

In productBaseRepository I have this call在 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;
    }

I have created DTO convertion function我创建了 DTO 转换 function

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;
    }

But then I call this function from swagger但后来我从 swagger 调用这个 function

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

I get that System.Text.Json.JsonException: A possible object cycle was detected.我得到 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这可能是由于循环或 object 深度大于最大允许深度 32

If I remove variants from call it works, so I need to some how remove Unecessry values from Variants如果我从调用中删除变体它会起作用,所以我需要一些如何从变体中删除不必要的值

The problem happens because your ProductVariant references ProductSize and ProductColor and ProductSize and ProductColor reference a list of ProductVariant objects.出现此问题是因为您的ProductVariant引用了ProductSizeProductColor ,而ProductSizeProductColor引用了ProductVariant对象的列表。 And ProductVariant has a reference to its BaseProduct . ProductVariant引用了它的BaseProduct This creates a cycle, two objects referencing each other.这创建了一个循环,两个对象相互引用。

In order to solve this issue, remove productVariant List from ProductSize and ProductColor or remove the ProductSize and ProductColor references from ProductVariant .为了解决此问题,请从ProductSizeProductColor中删除productVariant List 或从ProductVariant中删除ProductSizeProductColor引用。 Also remove the productBase reference from ProductVariant .同时从ProductVariant中删除productBase引用。

Use the IDs to find object references if required instead of having circular object references.如果需要,使用 ID 查找 object 引用,而不是循环引用 object。

See prevent property from being serialized in web API on how to prevent properties from being serialized without removing the property declaration from the class.请参阅web API 中的防止属性被序列化,了解如何在不从 class 中删除属性声明的情况下防止属性被序列化。

This is because Variants has a reference to its parents type, You could simply set this to null, eg这是因为Variants有一个对其父类型的引用,您可以简单地将其设置为 null,例如

foreach(var x in baseProduct.SelectMany(c => c.Variants) { x.ProductBase = null }

We ussually have different viewmodels to stop these cycles, eg:我们通常有不同的视图模型来停止这些循环,例如:

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
}

Note that the exception message should tell you where the issue is for example $.Variants.productBase.variants.productBase.variants or something similar.请注意,异常消息应该告诉您问题出在哪里,例如$.Variants.productBase.variants.productBase.variants或类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM