OData / OData/AspNetCoreOData

Composite Key not working, when one of Key matches name of other Entity

Open
#518 4 comments 0 reactions 1 assignee View on GitHub

@xuzhg is already working on this.

Since Mar 15, 2022.

followup
Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Description

Hi!

When configuring Composite Key for one of tables we got problem with key.
We had two entities:

public class PurchaseOrder
{
    public long Id { get; set; } //Key
    public string Name { get; set;}
    public IEnumerable<PurchaseOrderLine> PurchaseOrderLines { get; set; } = new List<PurchaseOrderLine>();
}
public class PurchaseOrderLine
{
    public long PurchaseOrderId { get; set; } //Part of Key
    public int LineId { get; set; } //Part of Key
    public string Name { get; set;}
    public PurchaseOrder? PurchaseOrder { get; set; }
}

Then we configure it as follows:

builder.EntitySet<PurchaseOrder>("PurchaseOrders");
builder.EntitySet<PurchaseOrderLine>("PurchaseOrderLines").EntityType
    .HasKey(pol => new {pol.PurchaseOrderId, pol.LineId});

Finally, we had PurchaseOrderController:

public class PurchaseOrderLinesController : ODataController
{
    private readonly IEnumerable<PurchaseOrderLine> _purchaseOrderLines; 
    
    // code to setup _purchaseOrderLines in ctor

    [EnableQuery]
    public IQueryable<PurchaseOrderLine> Get() => _purchaseOrderLines.AsQueryable();

    [EnableQuery]
    public SingleResult<PurchaseOrderLine> Get(long keyPurchaseOrderId, int keyLineId)
    {
        _logger.Log("Retrieving PurchaseOrder by composite key");
        var result = _purchaseOrderLines.AsQueryable().Where(m => m.PurchaseOrderId == keyPurchaseOrderId && m.LineId == keyLineId);
        return SingleResult.Create(result);
    }
}

When we call {host}/PurchaseOrderLines(PurchaseOrderId=1,LineId=1) we are not hitting the endpoint. 404 is returned, but no log trace (so it's 404, that enpoint not found, not that no entity with such id exist);

Funny thing is, that if we change PurchaseOrderId to HeadId, then it works:

builder.EntitySet<PurchaseOrder>("PurchaseOrders");
builder.EntitySet<PurchaseOrderLine>("PurchaseOrderLines").EntityType
    .HasKey(pol => new {pol.HeadId, pol.LineId});
        
        
[EnableQuery]
public SingleResult<PurchaseOrderLine> Get(long keyHeadId, int keyLineId)
{
    var result = _repository.Query()
        .Where(m => m.HeadId == keyHeadId && m.LineId == keyLineId);
    return SingleResult.Create(result);
}

Is it a bug, or there is some not documented convention that prevents using keys, which have similar names that other entities?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.