Мне нужно вернуть список сущностей (предложений) из контроллера оддаты, но он также должен вместе с ним вернуть еще одну сущность свойства (Summary), которая заполняется из метода Summarize. Эта другая сущность не сохраняется и не существует в dbcontext (builder.Ignore (p => p.Summary)).
Проблема в том, что он не может быть сложным типом для моего использования, поэтому я попытался добавить его в качестве EntitySet в buiilder и автоматически развернуть в родительском (так как я не могу добавить его в запрос, развернуть) , но каждый раз, когда я пытаюсь сделать запрос, возникает следующее исключение.
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();