在odata控制器上返回未映射的其他实体

时间:2018-09-03 13:49:20

标签: .net-core odata

我需要从odata控制器返回一个实体列表(建议),但是它还需要与另一个从Summarize方法填充的Property实体一起(汇总)一起返回。此其他实体不会持久存在,也不存在于dbcontext中(builder.Ignore(p => p.Summary))。

问题在于它不能作为我的复杂类型,因此我尝试将其添加为BUILILDER上的EntitySet并在父级上自动扩展(因为我无法将其添加到扩展查询中) ,但是每次我尝试查询它时,都会引发以下异常。

System.Runtime.Serialization.SerializationException: Cannot serialize a null 'ResourceSet'.
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext) [...]

我想知道是否由于上下文不存在该实体而发生这种情况。

那么有没有办法使这项工作呢?不会保留另一个实体,而是将其连同其父级的odata查询一起返回?

结果:

{"@odata.context":"http://localhost:57450/OData/$metadata#Proposal","value":[{"ProposalID":"e91cacfc-f345-4617-bd54-b1f440e4fd65","CustomerNumber":null,"Description":"","ServiceType":"LeaseReturn","Currency":null,"PartnerName":null,"QuoteDate":"0001-01-01T00:00:00-02:00","CreatedOn":"2018-08-06T16:27:52.8169404-03:00","CreatedBy":"Admin","UpdatedOn":null,"UpdatedBy":null,"ProposalServiceFees":[]},{"ProposalID":"28ddfea6-2ac9-4898-b72f-d5e284d5072f","CustomerNumber":"2","Description":"a","ServiceType":"ResaleAndRecycle","Currency":null,"PartnerName":null,"QuoteDate":"0001-01-01T00:00:00-02:00","CreatedOn":"2018-08-15T15:11:07.531755-03:00","CreatedBy":"Admin","UpdatedOn":null,"UpdatedBy":null,"ProposalServiceFees":[]}]}

预期:

{"@odata.context":"http://localhost:57450/OData/$metadata#Proposal","value":[{"ProposalID":"e91cacfc-f345-4617-bd54-b1f440e4fd65","CustomerNumber":null,"Description":"","ServiceType":"LeaseReturn","Currency":null,"PartnerName":null,"QuoteDate":"0001-01-01T00:00:00-02:00","CreatedOn":"2018-08-06T16:27:52.8169404-03:00","CreatedBy":"Admin","UpdatedOn":null,"UpdatedBy":null,"Summary":{"SummaryId":"e91cacfc-f345-4617-bd54-b1f440e4fd65","Items":[{"Type":"workstation","Price":0.00}],"Fees":[]},"ProposalServiceFees":[]},{"ProposalID":"28ddfea6-2ac9-4898-b72f-d5e284d5072f","CustomerNumber":"2","Description":"a","ServiceType":"ResaleAndRecycle","Currency":null,"PartnerName":null,"QuoteDate":"0001-01-01T00:00:00-02:00","CreatedOn":"2018-08-15T15:11:07.531755-03:00","CreatedBy":"Admin","UpdatedOn":null,"UpdatedBy":null,"Summary":{"SummaryId":"28ddfea6-2ac9-4898-b72f-d5e284d5072f","Items":[{"Type":"strings","Price":0.00}],"Fees":[]},"ProposalServiceFees":[]}]}

实体:

public class Proposal : EntityBase {
    public Guid ProposalID { get; set; }
    public string CustomerNumber { get; set; }
    public string Description { get; set; }
    public string ServiceType { get; set; }
    public string Currency { get; set; }
    public Summary Summary { get; set; }
    public string PartnerName { get; set; }
    public DateTime QuoteDate { get; set; }
 [...]
    public void Summarize()
        => Summary = new Summary(Assets, ProposalServiceFees.Select(f=>f.ServiceFee), ProposalID);
 }

 public class Summary
 {
    public Guid SummaryId { get; set; }
    public IEnumerable<SummaryItem> Items { get; private set; }
    public IEnumerable<SummaryItem> Fees { get; private set; }

    internal Summary(IEnumerable<Asset> assets, IEnumerable<ServiceFee> fees, Guid id)
    {
        SummaryId = id;  //dummy for test

        Items = assets
            .GroupBy(asset => asset.ProductType, GroupIntoSummaryItem)
            .ToList();

        Fees = fees
            .Select(f=> FeeToSummaryItem(f.ApplyServiceFee(assets.Count())))
            .ToList();
    }
    [...]
}

控制器:

    [EnableQuery]
    [ODataRoute()]
    public IQueryable<Proposal.Domain.Entities.Proposal> Get(ODataQueryOptions opts)
    {
        opts.Validate(settings);

        IQueryable results = opts.ApplyTo(_context.Proposal.Include(x => x.Assets)).AsQueryable();

        var values = (results as IQueryable<Proposal.Domain.Entities.Proposal>)?.ToList();

        values?.ForEach(x => x.Summarize());

        return values?.AsQueryable();
    }

OdataConventionModelBuilder:

        EntitySet<Summary>(nameof(Summary))
            .EntityType
            .HasKey(p => p.SummaryId)
            .Filter()
            .Count()
            .Expand()
            .OrderBy()
            .Page()
            .Select();

        EntitySet<Domain.Entities.Proposal>(nameof(Domain.Entities.Proposal))
            .EntityType
            .HasKey(p => p.ProposalID)
            .Expand(SelectExpandType.Automatic, nameof(Summary))
            .Filter()
            .Count()
            .Expand()
            .OrderBy()
            .Page()
            .Select();

1 个答案:

答案 0 :(得分:0)

这很可能是由于您的模型结构与数据库结构不匹配。当您剪切/粘贴并忘记重命名实体时,这种情况经常发生。