【问题标题】:Returning multiple lists data inside an object in ASP dotnet Core API在 ASP dotnet Core API 中返回对象内的多个列表数据
【发布时间】:2020-06-20 12:17:00
【问题描述】:

我有这个寄售实体模型。

public Guid Id { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public bool? Deleted { get; set; }
public string Status { get; set; }
public string Services { get; set; }
public string CustomerReference { get; set; }
public string ConsignmentNote { get; set; }
public int? TotalPieces { get; set; }
...
public virtual ICollection<ConsignmentDocument> ConsignmentDocument { get; set; }
public virtual ICollection<ConsignmentLine> ConsignmentLine { get; set; }
public virtual ICollection<Legging> Legging { get; set; }

现在我在取货时面临的问题是我没有在响应正文中获得任何 ConsignmentLine、Legging、ConsignmentDocument 的数据。我在我的寄售控制器中仅使用寄售线对其进行测试。这是我的 GetConsignment() 控制器方法。

// GET: api/Consignments
    [HttpGet("{id}")]
    public async Task<ActionResult<Consignment>> GetConsignment(Guid id)
    {
        var consignment = await _context.Consignment.where(c =>c.Id == id)
            .Include(conline => conline.ConsignmentLine)
            .FirstOrDefault();
        return consignment;
    }

我的 ConsignmentLine.cs 是这样的:

    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal? Length { get; set; }
    public decimal? Width { get; set; }
    public decimal? Height { get; set; }
    public decimal? Volume { get; set; }
    public int? Pieces { get; set; }
    public decimal? Weigth { get; set; }
    public bool? DangerousGoods { get; set; }
    public string DgClass { get; set; }
    public string UnNumber { get; set; }
    public Guid? ConsignmentId { get; set; }
    public Guid? ItemId { get; set; }
    public Guid? CommodityId { get; set; }
    public bool? Deleted { get; set; }

我的 Legging.cs 是这样的:

    public Guid Id { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public decimal? Cost { get; set; }
    public string LegType { get; set; }
    public string FromLeg { get; set; }
    public string ToLeg { get; set; }
    public Guid? CarrierAccount { get; set; }
    public Guid? ConsignmentId { get; set; }
    public bool? Deleted { get; set; }

我正在从邮递员那里测试它,它正在返回 Json 异常。那应该怎么表达呢?

【问题讨论】:

  • 您能提出任何替代方案吗?
  • 如回答中所说:您甚至不需要Where
  • 但是 FirstOrDefault() 返回错误!
  • 您的代码中没有FirstOrDefault,只是告诉它“返回错误”是没有意义的。此外,你真的应该展示完整的课程。看起来您在 JSON 序列化中遇到了臭名昭著的循环引用错误。很容易找到解决此问题的方法。
  • @GertArnold 谢谢。解决了。必须安装 NewtonsoftJson 包并将其注入服务。

标签: entity-framework linq .net-core controller asp.net-core-webapi


【解决方案1】:

问题在于 Lambda 表达式。到目前为止,您无法过滤 Include 语句。如果您想要过滤结果,则必须将它们全部提取到内存并过滤它们。在您的情况下,您甚至不需要过滤包含部分。只包括导航属性就可以正常工作。假设该参数用于过滤寄售表。

    // GET: api/Consignments
    [HttpGet("{id}")]
    public async Task<ActionResult<Consignment>> GetConsignment(Guid id)
    {
        var consignment = await _context.Consignment.Where(x=>x.Id == id)
                .Include(conline => conline.ConsignmentLine)
                .FirstOrDefault();
        return consignment;
    }

上面的代码将简单地为您提供来自Consignmet 表及其ConsignmentLine 的记录。尝试让我知道这是否有效。

但是,这可能会引发JSON.NET Error Self-referencing loop detected for type error。如果您收到此错误,则可以使用以下方法解决此错误。

如果您使用的是 AspNet Core,请将以下内容添加到 ConfigureServices() 方法中。

services.AddMvc()
    .AddJsonOptions(
        options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );

快乐编码。

【讨论】:

  • 你能再看看我的问题吗?我也提供了我的 ConsignmentLine 和 Legging 课程。更新后的控制器代码向我抛出了 -JSON 对象异常。
  • 那么这可能是 JSON 序列化程序的问题。我已经更新了答案。请看一看。
  • 是的,这是 JSON 序列化程序的问题。昨天修好了。谢谢你的建议。
【解决方案2】:

正如评论所说,您不能在包含中使用任何过滤。

而GetConsignment方法返回的是Consignment的类型,而不是列表集合,因此需要通过FirstOrDefaultAsyncSingleOrDefaultAsync转换consignment变量。

尝试将代码更改为以下内容:

public async Task<ActionResult<Consignment>>  GetConsignment(Guid id)       
{ 
        var consignment = await _context.Consignment.Where(x=>x.Id == id)
        .Include(conline => conline.ConsignmentLine)
        .FirstOrDefaultAsync();

        return consignment; 
}

这是我的 ConsignmentLine.cs :

 public class ConsignmentLine
{
    public int Id { get; set; }
}

在linq中加载相关数据可以参考this

【讨论】:

  • 我已经更新了我的问题,你能再看看吗?
  • @ShakerKamal,我使用了你的ConsignmentLine模型,结果和我的demo一样,你可以用我的代码来测试,不要在Include中使用where。并使用 FirstOrDefaultAsync。
猜你喜欢
  • 1970-01-01
  • 2022-08-07
  • 1970-01-01
  • 2021-03-14
  • 2021-09-03
  • 2021-09-28
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
相关资源
最近更新 更多