Skip to content

Commit

Permalink
DeltaOfT out of sync with WebAPI: missing UpdatableProperties
Browse files Browse the repository at this point in the history
  • Loading branch information
dxrdxr authored and xuzhg committed Aug 31, 2021
1 parent 97f9cde commit 04541a2
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 57 deletions.
39 changes: 21 additions & 18 deletions src/Microsoft.AspNetCore.OData/Deltas/DeltaOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ namespace Microsoft.AspNetCore.OData.Deltas
public class Delta<T> : Delta, IDelta, ITypedDelta where T : class
{
// cache property accessors for this type and all its derived types.
private static ConcurrentDictionary<Type, Dictionary<string, PropertyAccessor<T>>> _propertyCache
private static readonly ConcurrentDictionary<Type, Dictionary<string, PropertyAccessor<T>>> _propertyCache
= new ConcurrentDictionary<Type, Dictionary<string, PropertyAccessor<T>>>();

private Dictionary<string, PropertyAccessor<T>> _allProperties;
private HashSet<string> _updatableProperties;
private List<string> _updatableProperties;

private HashSet<string> _changedProperties;

Expand All @@ -39,7 +39,7 @@ private static ConcurrentDictionary<Type, Dictionary<string, PropertyAccessor<T>
private T _instance;
private Type _structuredType;

private PropertyInfo _dynamicDictionaryPropertyinfo;
private readonly PropertyInfo _dynamicDictionaryPropertyinfo;
private HashSet<string> _changedDynamicProperties;
private IDictionary<string, object> _dynamicDictionaryCache;

Expand Down Expand Up @@ -98,16 +98,19 @@ public Delta(Type structuralType, IEnumerable<string> updatableProperties,

/// <inheritdoc/>
public virtual Type StructuredType
{
get
{
return _structuredType;
}
}
=> _structuredType;

/// <inheritdoc/>
public virtual Type ExpectedClrType => typeof(T);

/// <summary>
/// The list of property names that can be updated.
/// </summary>
/// <remarks>When the list is modified, any modified properties that were removed from the list are no longer
/// considered to be changed.</remarks>
public IList<string> UpdatableProperties
=> _updatableProperties;

/// <inheritdoc/>
public override void Clear()
{
Expand Down Expand Up @@ -172,7 +175,7 @@ public override bool TryGetPropertyValue(string name, out object value)
}
}

if (this._deltaNestedResources.ContainsKey(name))
if (_deltaNestedResources.ContainsKey(name))
{
// If this is a nested resource, get the value from the dictionary of nested resources.
object deltaNestedResource = _deltaNestedResources[name];
Expand Down Expand Up @@ -259,7 +262,7 @@ public T GetInstance()
/// </summary>
public override IEnumerable<string> GetChangedPropertyNames()
{
return _changedProperties.Concat(_deltaNestedResources.Keys);
return _changedProperties.Intersect(_updatableProperties).Concat(_deltaNestedResources.Keys);
}

/// <summary>
Expand All @@ -269,7 +272,8 @@ public override IEnumerable<string> GetChangedPropertyNames()
/// </summary>
public override IEnumerable<string> GetUnchangedPropertyNames()
{
return _updatableProperties.Except(GetChangedPropertyNames());
// UpdatableProperties could include arbitrary strings, filter by _allProperties
return _updatableProperties.Intersect(_allProperties.Keys).Except(GetChangedPropertyNames());
}

/// <summary>
Expand All @@ -295,7 +299,7 @@ public void CopyChangedValues(T original)

// For regular non-structural properties at current level.
PropertyAccessor<T>[] propertiesToCopy =
this._changedProperties.Select(s => _allProperties[s]).ToArray();
_changedProperties.Intersect(_updatableProperties).Select(s => _allProperties[s]).ToArray();
foreach (PropertyAccessor<T> propertyToCopy in propertiesToCopy)
{
propertyToCopy.Copy(_instance, original);
Expand Down Expand Up @@ -498,12 +502,11 @@ private void InitializeProperties(IEnumerable<string> updatableProperties)

if (updatableProperties != null)
{
_updatableProperties = new HashSet<string>(updatableProperties);
_updatableProperties.IntersectWith(_allProperties.Keys);
_updatableProperties = updatableProperties.Intersect(_allProperties.Keys).ToList();
}
else
{
_updatableProperties = new HashSet<string>(_allProperties.Keys);
_updatableProperties = new List<string>(_allProperties.Keys);
}

if (_dynamicDictionaryPropertyinfo != null)
Expand Down Expand Up @@ -618,7 +621,7 @@ private bool TrySetPropertyValueInternal(string name, object value)
throw Error.ArgumentNull("name");
}

if (!_updatableProperties.Contains(name))
if (!(_allProperties.ContainsKey(name) && _updatableProperties.Contains(name)))
{
return false;
}
Expand Down Expand Up @@ -648,7 +651,7 @@ private bool TrySetNestedResourceInternal(string name, object deltaNestedResourc
throw Error.ArgumentNull("name");
}

if (!_updatableProperties.Contains(name))
if (!(_allProperties.ContainsKey(name) && _updatableProperties.Contains(name)))
{
return false;
}
Expand Down
7 changes: 7 additions & 0 deletions src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1615,6 +1615,13 @@
<member name="P:Microsoft.AspNetCore.OData.Deltas.Delta`1.ExpectedClrType">
<inheritdoc/>
</member>
<member name="P:Microsoft.AspNetCore.OData.Deltas.Delta`1.UpdatableProperties">
<summary>
The list of property names that can be updated.
</summary>
<remarks>When the list is modified, any modified properties that were removed from the list are no longer
considered to be changed.</remarks>
</member>
<member name="M:Microsoft.AspNetCore.OData.Deltas.Delta`1.Clear">
<inheritdoc/>
</member>
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AspNetCore.OData/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ Microsoft.AspNetCore.OData.Deltas.Delta<T>.Delta(System.Type structuralType, Sys
Microsoft.AspNetCore.OData.Deltas.Delta<T>.GetInstance() -> T
Microsoft.AspNetCore.OData.Deltas.Delta<T>.Patch(T original) -> void
Microsoft.AspNetCore.OData.Deltas.Delta<T>.Put(T original) -> void
Microsoft.AspNetCore.OData.Deltas.Delta<T>.UpdatableProperties.get -> System.Collections.Generic.IList<string>
Microsoft.AspNetCore.OData.Deltas.DeltaDeletedResource<T>
Microsoft.AspNetCore.OData.Deltas.DeltaDeletedResource<T>.DeltaDeletedResource() -> void
Microsoft.AspNetCore.OData.Deltas.DeltaDeletedResource<T>.DeltaDeletedResource(System.Type structuralType) -> void
Expand Down
Loading

0 comments on commit 04541a2

Please sign in to comment.