Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite key entities PUT,PATCH URIs generated by OData Client do not follow key order #2598

Closed
KaltrinI opened this issue Jan 17, 2023 · 3 comments · Fixed by #2603
Closed
Assignees

Comments

@KaltrinI
Copy link

KaltrinI commented Jan 17, 2023

Short summary (3-5 sentences) describing the issue.
When an entity has a composite key, the URIs are generated for an update of the entity, following the update route pattern for named keys (ex. "AEntities(CPk1={keyPk1}, BPk2={keyPk2},APk3={keyPk3})") does not map the keys accordingly, rather it generates an URI (ex. "AEntities(APk3={keyPk3}, BPk2={keyPk2},CPk3={keyPk1})") which causes an exception because the third part of the key gets assigned to the first part.

Assemblies affected

OData .Net lib 7.x*

Reproduce steps

Create an ASP Web API, an OData Connected Service, and a Unit Test project (that can be used for integration testing).
The models are attached in the ZIP file. Create OData Controllers for the entities and define the custom URIs for HttpPut and HttpPatch following the above convention.

In the unit test project, try to update an entity of type AEntity using the OData Client.

Expected result

  • The URI for update is "AEntities(CPk1={keyPk1}, BPk2={keyPk2},APk3={keyPk3})";
  • OData Client maps the keys to their corresponding position in the URL

Actual result

  • Odata Client tries to assign the value of APk3={keyPk3} to the first position ( Cpk1={keyPk1} ) and it crashes with type mismatch for the key.

Additional detail

I am working on a test project where all of this is set up. In the meantime, feel free to request more information about the bug if the description is not clear.
Models.zip

@xuzhg
Copy link
Member

xuzhg commented Jan 17, 2023

@KaltrinI How do you use ODataClient to generate the OData request?

I have the following tests:

var container = new Container(new Uri("http://localhost:5298/odata"));
var aEntities1 = container.AEntities.Where(a => a.CId == 8 && a.AId == "a" && a.BId == "b");  // #1
var aEntities2 = container.AEntities.Where(a => a.CId == 8 && a.BId == "baba" && a.AId == "aa" ); // #2

ODataClient generates the following two requests based on the above two 'Where' clauses.

image

It seems you have put different orders in "where" clause, it will generate different orders.

I attached my test project. Hope it can help.

odl_issue2598.zip

@mikepizzo

@mikepizzo
Copy link
Member

@xuzhg --
Since we are translating the filter condition to a key lookup (which, I believe, can now be disabled) we should generate the key values in the correct sequence (should be easy enough to add this ordering to OData Client).

However, I think the real issue is that when you try to update/delete one of the entities fetched from the above queries, OData Client generates a request that should be the canonical URL, based on the order of keys in the CSDL, but is not.

@KaltrinI
Copy link
Author

KaltrinI commented Jan 18, 2023

@xuzhg this is the code I use to track an already existing entity

func(entity){
context.AttachTo(entity.GetEntitySetName(), entity);

var collection = new DataServiceCollection<TEntity>(context);

var attachedEntity = (TEntity) context.GetEntityDescriptor(entity).Entity;


collection.Load(attachedEntity);


}

After this, I update some property values of the entity.

Next step I call

context.UpdateObject(entity, PostOnlySetProperites) or context.UpdateObject(entity, ReplaceOnUpdate) // both have the same problem

context.SaveChangesAsync();

What I am able to see while debugging, the RouteValueDictionary from ODataTemplateTranslateContext, has wrong key-value pairs assigned (surprisingly they are arranged in alphabetical order, which I do not know is it just a coincidence or has it got something to do with the issue).

That being said, it fails on ReadLiteralToken.

Microsoft.OData.ODataException: Expected literal type token but found token '...'

xuzhg added a commit that referenced this issue Jan 19, 2023
xuzhg added a commit that referenced this issue Jan 31, 2023
xuzhg added a commit that referenced this issue Feb 1, 2023
@xuzhg xuzhg closed this as completed in 6fd00a7 Feb 14, 2023
xuzhg added a commit that referenced this issue Feb 15, 2023
… Client do not follow key order (#2603)

* fixes #2598, Composite key entities PUT,PATCH URIs generated by OData Client do not follow key order

* Add more tests and fix the failing test cases

* Fix the failing test cases.

* Add the comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants