Skip to content

Enable the nested delta collection deep update - #747

Merged
xuzhg merged 2 commits into
mainfrom
issue743
Dec 1, 2022
Merged

Enable the nested delta collection deep update#747
xuzhg merged 2 commits into
mainfrom
issue743

Conversation

@xuzhg

@xuzhg xuzhg commented Nov 18, 2022

Copy link
Copy Markdown
Member

Issue #743

Enable the deep update for the nested delta collection.

Request Header:

Content-Type: application/json
OData-Version: 4.01
OData-MaxVersion: 4.01

Patch to single entity with nested delta collection:

{
	"name":"anothertest",
	"@id": "Order(2)",
	"items@delta":[
	  {
		"@id": "OrderItems(2, 1)",
		"price":0
	  },
	  {
	    "@removed":{
			"reason":"deleted"
			},
		"@id": "OrderItems(2, 2)"
		}
     ]
}

Patch to single entity with nested collection:

{
	"name":"anothertest",
	"@id": "Order(2)",
	"items":[
	  {
		"price":0
	  },
	  {
	    "price":1
      }
  ]
}

}

if (value is IDelta)
if (value is IDelta || value is IDeltaSet)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use or pattern matching here:

Suggested change
if (value is IDelta || value is IDeltaSet)
if (value is IDelta or IDeltaSet)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's C# 9 feature and it seems we have to update the csproj to enable C# 9 language.
I don't want to introduce that changes in this PR. Thanks.


Contract.Assert(deltaNestedResource != null, "deltaNestedResource != null");

//If DeltaSet collection, we are handling delta collections so the value will be that itself and no need to get instance value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//If DeltaSet collection, we are handling delta collections so the value will be that itself and no need to get instance value
// If DeltaSet collection, we are handling delta collections so the value will be that itself and no need to get instance value


if (deltaNestedResource is IDeltaSet)
{
// TODO: That's the bulk insert OData Path handler feature,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of leaving a TODO in the code, I'd suggest adding a link to an issue in github documenting this feature.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#resolved.

FieldInfo field = deltaNestedResource.GetType().GetField("_instance", BindingFlags.NonPublic | BindingFlags.Instance);
Contract.Assert(field != null, "field != null");
cacheHit.SetValue(_instance, field.GetValue(deltaNestedResource));
if (!(deltaNestedResource is IDeltaSet))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!(deltaNestedResource is IDeltaSet))
if (deltaNestedResource is not IDeltaSet)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the above one. That's C# 9 feature and I 'd skip it in this PR. Thanks.

{
PropertyAccessor<T> cacheHit = _allProperties[name];
// Get the Delta<{NestedResourceType}>._instance using Reflection.
FieldInfo field = deltaNestedResource.GetType().GetField("_instance", BindingFlags.NonPublic | BindingFlags.Instance);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this was already like this in the previous code, but why do we use reflection on a type that we own? Or am I missing something here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think deltaNestedResource is a generic type instance, DeltaSet< T >. We don't know the real type until running.

/// <param name="model">The Edm model.</param>
/// <param name="structuredType">The given structured type.</param>
/// <returns>All property names.</returns>
public static IList<string> GetAllProperties(this IEdmModel model, IEdmStructuredType structuredType)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't seem to require index access to this collection, so I'd suggest ICollection instead of IList.

Having said that, can we use either a readonly or an immutable variant?

Alternatively, this could be an iterator method which would not require allocating a collection and would lead to simpler code as well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed as suggested. Thanks.

Comment on lines +119 to +120
IDeltaSet set = value as IDeltaSet;
if (set != null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
IDeltaSet set = value as IDeltaSet;
if (set != null)
if (value is IDeltaSet set)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#resolved.

@vcantor vcantor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. The deltaset can be obtained using TryGetPropertyValue. Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to use deep update on nested collections

3 participants