- fixes #129 a bug where odata count paths would be missing from the description
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
This commit is contained in:
parent
f08be6482f
commit
ae11d65007
|
@ -12,6 +12,10 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// </summary>
|
||||
public class ODataDollarCountSegment : ODataSegment
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the static instance of $count segment.
|
||||
/// </summary>
|
||||
internal static ODataDollarCountSegment Instance = new();
|
||||
/// <inheritdoc />
|
||||
public override ODataSegmentKind Kind => ODataSegmentKind.DollarCount;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
|
||||
private IEnumerable<ODataPath> MergePaths()
|
||||
{
|
||||
List<ODataPath> allODataPaths = new List<ODataPath>();
|
||||
List<ODataPath> allODataPaths = new();
|
||||
foreach (var item in _allNavigationSourcePaths.Values)
|
||||
{
|
||||
allODataPaths.AddRange(item);
|
||||
|
@ -127,6 +127,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
ODataPathKind kind = path.Kind;
|
||||
switch(kind)
|
||||
{
|
||||
case ODataPathKind.DollarCount:
|
||||
case ODataPathKind.Entity:
|
||||
case ODataPathKind.EntitySet:
|
||||
case ODataPathKind.Singleton:
|
||||
|
@ -143,8 +144,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
|
||||
case ODataPathKind.NavigationProperty:
|
||||
case ODataPathKind.Ref:
|
||||
ODataNavigationPropertySegment navigationPropertySegment = path.Last(p => p is ODataNavigationPropertySegment)
|
||||
as ODataNavigationPropertySegment;
|
||||
ODataNavigationPropertySegment navigationPropertySegment = path.OfType<ODataNavigationPropertySegment>().Last();
|
||||
|
||||
if (!_allNavigationPropertyPaths.TryGetValue(navigationPropertySegment.EntityType, out IList<ODataPath> npList))
|
||||
{
|
||||
|
@ -174,15 +174,17 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
Debug.Assert(navigationSource != null);
|
||||
|
||||
// navigation source itself
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(navigationSource));
|
||||
ODataPath path = new(new ODataNavigationSourceSegment(navigationSource));
|
||||
AppendPath(path.Clone());
|
||||
|
||||
IEdmEntitySet entitySet = navigationSource as IEdmEntitySet;
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
|
||||
// for entity set, create a path with key
|
||||
// for entity set, create a path with key and a $count path
|
||||
if (entitySet != null)
|
||||
{
|
||||
CreateCountPath(path);
|
||||
|
||||
path.Push(new ODataKeySegment(entityType));
|
||||
AppendPath(path.Clone());
|
||||
}
|
||||
|
@ -275,6 +277,13 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
if (restriction == null || restriction.IndexableByKey == true)
|
||||
{
|
||||
IEdmEntityType navEntityType = navigationProperty.ToEntityType();
|
||||
var targetsMany = navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many;
|
||||
|
||||
if (targetsMany)
|
||||
{
|
||||
// ~/entityset/{key}/collection-valued-Nav/$count
|
||||
CreateCountPath(currentPath);
|
||||
}
|
||||
|
||||
if (!navigationProperty.ContainsTarget)
|
||||
{
|
||||
|
@ -283,7 +292,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
// Collection-valued: ~/entityset/{key}/collection-valued-Nav/$ref?$id ={navKey}
|
||||
CreateRefPath(currentPath);
|
||||
|
||||
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
if (targetsMany)
|
||||
{
|
||||
// Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref
|
||||
currentPath.Push(new ODataKeySegment(navEntityType));
|
||||
|
@ -296,7 +305,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
else
|
||||
{
|
||||
// append a navigation property key.
|
||||
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
if (targetsMany)
|
||||
{
|
||||
currentPath.Push(new ODataKeySegment(navEntityType));
|
||||
AppendPath(currentPath.Clone());
|
||||
|
@ -318,7 +327,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
}
|
||||
|
||||
if (navigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
if (targetsMany)
|
||||
{
|
||||
currentPath.Pop();
|
||||
}
|
||||
|
@ -360,6 +369,16 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
newPath.Push(ODataRefSegment.Instance); // $ref
|
||||
AppendPath(newPath);
|
||||
}
|
||||
/// <summary>
|
||||
/// Create $count paths.
|
||||
/// </summary>
|
||||
/// <param name="currentPath">The current OData path.</param>
|
||||
private void CreateCountPath(ODataPath currentPath) {
|
||||
if(currentPath == null) throw new ArgumentNullException(nameof(currentPath));
|
||||
var countPath = currentPath.Clone();
|
||||
countPath.Push(ODataDollarCountSegment.Instance);
|
||||
AppendPath(countPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all bounding <see cref="IEdmOperation"/>.
|
||||
|
@ -436,7 +455,11 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HashSet<ODataPathKind> _oDataPathKindsToSkipForOperations = new HashSet<ODataPathKind>() {
|
||||
ODataPathKind.EntitySet,
|
||||
ODataPathKind.MediaEntity,
|
||||
ODataPathKind.DollarCount
|
||||
};
|
||||
private bool AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -448,8 +471,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
foreach (var subPath in value)
|
||||
{
|
||||
if ((isCollection && subPath.Kind == ODataPathKind.EntitySet) ||
|
||||
(!isCollection && subPath.Kind != ODataPathKind.EntitySet &&
|
||||
subPath.Kind != ODataPathKind.MediaEntity))
|
||||
(!isCollection && !_oDataPathKindsToSkipForOperations.Contains(subPath.Kind)))
|
||||
{
|
||||
ODataPath newPath = subPath.Clone();
|
||||
newPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction));
|
||||
|
@ -461,7 +483,9 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
|
||||
return found;
|
||||
}
|
||||
|
||||
private static readonly HashSet<ODataPathKind> _pathKindToSkipForNavigationProperties = new () {
|
||||
ODataPathKind.Ref,
|
||||
};
|
||||
private bool AppendBoundOperationOnNavigationPropertyPath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -469,13 +493,8 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
|
||||
if (_allNavigationPropertyPaths.TryGetValue(bindingEntityType, out IList<ODataPath> value))
|
||||
{
|
||||
foreach (var path in value)
|
||||
foreach (var path in value.Where(x => !_pathKindToSkipForNavigationProperties.Contains(x.Kind)))
|
||||
{
|
||||
if (path.Kind == ODataPathKind.Ref)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ODataNavigationPropertySegment npSegment = path.Segments.Last(s => s is ODataNavigationPropertySegment) as ODataNavigationPropertySegment;
|
||||
|
||||
if (!npSegment.NavigationProperty.ContainsTarget)
|
||||
|
@ -596,15 +615,9 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
{
|
||||
if (_allNavigationPropertyPaths.TryGetValue(baseType, out IList<ODataPath> paths))
|
||||
{
|
||||
foreach (var path in paths)
|
||||
foreach (var path in paths.Where(x => !_pathKindToSkipForNavigationProperties.Contains(x.Kind)))
|
||||
{
|
||||
if (path.Kind == ODataPathKind.Ref)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var npSegment = path.Segments.Last(s => s is ODataNavigationPropertySegment)
|
||||
as ODataNavigationPropertySegment;
|
||||
var npSegment = path.Segments.OfType<ODataNavigationPropertySegment>().LastOrDefault();
|
||||
if (npSegment == null)
|
||||
{
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue