[Fix] Generate paths for stream properties in base types of entities (#110)
* Get all properties declared in type def. including base types * Update/refactor tests to validate stream props. of base types are captured * Refactor Handler class to use encapsulation to define navigation sources
This commit is contained in:
parent
e8ecb37c96
commit
e6a5e52e11
|
@ -219,7 +219,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
||||||
Debug.Assert(currentPath != null);
|
Debug.Assert(currentPath != null);
|
||||||
|
|
||||||
bool createValuePath = true;
|
bool createValuePath = true;
|
||||||
foreach (IEdmStructuralProperty sp in entityType.DeclaredStructuralProperties())
|
foreach (IEdmStructuralProperty sp in entityType.StructuralProperties())
|
||||||
{
|
{
|
||||||
if (sp.Type.AsPrimitive().IsStream())
|
if (sp.Type.AsPrimitive().IsStream())
|
||||||
{
|
{
|
||||||
|
@ -228,7 +228,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
||||||
currentPath.Pop();
|
currentPath.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp.Name.Equals("content", System.StringComparison.OrdinalIgnoreCase))
|
if (sp.Name.Equals("content", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
createValuePath = false;
|
createValuePath = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
protected override void SetBasicInfo(OpenApiOperation operation)
|
protected override void SetBasicInfo(OpenApiOperation operation)
|
||||||
{
|
{
|
||||||
// Summary
|
// Summary
|
||||||
if (IsNavigationPropertyPath)
|
operation.Summary = IsNavigationPropertyPath
|
||||||
{
|
? $"Get media content for the navigation property {NavigationProperty.Name} from {NavigationSource.Name}"
|
||||||
operation.Summary = $"Get media content for the navigation property {NavigationProperty.Name} from {NavigationSource.Name}";
|
: $"Get media content for {NavigationSourceSegment.EntityType.Name} from {NavigationSourceSegment.Identifier}";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IEdmEntityType entityType = EntitySet.EntityType();
|
|
||||||
operation.Summary = $"Get media content for {entityType.Name} from {EntitySet.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
// Description
|
||||||
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
|
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
|
||||||
|
@ -73,9 +67,8 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override void SetSecurity(OpenApiOperation operation)
|
protected override void SetSecurity(OpenApiOperation operation)
|
||||||
{
|
{
|
||||||
ReadRestrictionsType read = EntitySet != null
|
IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)NavigationSourceSegment.NavigationSource;
|
||||||
? Context.Model.GetRecord<ReadRestrictionsType>(EntitySet, CapabilitiesConstants.ReadRestrictions)
|
ReadRestrictionsType read = Context.Model.GetRecord<ReadRestrictionsType>(annotatableNavigationSource, CapabilitiesConstants.ReadRestrictions);
|
||||||
: Context.Model.GetRecord<ReadRestrictionsType>(Singleton, CapabilitiesConstants.ReadRestrictions);
|
|
||||||
if (read == null)
|
if (read == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -21,14 +21,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
internal abstract class MediaEntityOperationalHandler : NavigationPropertyOperationHandler
|
internal abstract class MediaEntityOperationalHandler : NavigationPropertyOperationHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets/sets the <see cref="IEdmEntitySet"/>.
|
/// Gets/Sets the NavigationSource segment
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IEdmEntitySet EntitySet { get; private set; }
|
protected ODataNavigationSourceSegment NavigationSourceSegment { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="IEdmSingleton"/>.
|
|
||||||
/// </summary>
|
|
||||||
protected IEdmSingleton Singleton { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets/Sets flag indicating whether path is navigation property path
|
/// Gets/Sets flag indicating whether path is navigation property path
|
||||||
|
@ -39,13 +34,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
protected override void Initialize(ODataContext context, ODataPath path)
|
protected override void Initialize(ODataContext context, ODataPath path)
|
||||||
{
|
{
|
||||||
// The first segment will either be an EntitySet navigation source or a Singleton navigation source
|
// The first segment will either be an EntitySet navigation source or a Singleton navigation source
|
||||||
ODataNavigationSourceSegment navigationSourceSegment = path.FirstSegment as ODataNavigationSourceSegment;
|
NavigationSourceSegment = path.FirstSegment as ODataNavigationSourceSegment;
|
||||||
EntitySet = navigationSourceSegment.NavigationSource as IEdmEntitySet;
|
|
||||||
|
|
||||||
if (EntitySet == null)
|
|
||||||
{
|
|
||||||
Singleton = navigationSourceSegment.NavigationSource as IEdmSingleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether path is a navigation property path
|
// Check whether path is a navigation property path
|
||||||
IsNavigationPropertyPath = Path.Segments.Contains(
|
IsNavigationPropertyPath = Path.Segments.Contains(
|
||||||
|
@ -67,9 +56,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string tagIdentifier = EntitySet.Name + "." + EntitySet.EntityType().Name;
|
string tagIdentifier = NavigationSourceSegment.Identifier + "." + NavigationSourceSegment.EntityType.Name;
|
||||||
|
|
||||||
OpenApiTag tag = new OpenApiTag
|
OpenApiTag tag = new()
|
||||||
{
|
{
|
||||||
Name = tagIdentifier
|
Name = tagIdentifier
|
||||||
};
|
};
|
||||||
|
@ -102,7 +91,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
|
|
||||||
IList<string> items = new List<string>
|
IList<string> items = new List<string>
|
||||||
{
|
{
|
||||||
EntitySet?.Name ?? Singleton.Name
|
NavigationSourceSegment.Identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
ODataSegment lastSegment = Path.Segments.Last(c => c is ODataStreamContentSegment || c is ODataStreamPropertySegment);
|
ODataSegment lastSegment = Path.Segments.Last(c => c is ODataStreamContentSegment || c is ODataStreamPropertySegment);
|
||||||
|
@ -112,7 +101,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
{
|
{
|
||||||
if (!IsNavigationPropertyPath)
|
if (!IsNavigationPropertyPath)
|
||||||
{
|
{
|
||||||
string typeName = EntitySet?.EntityType().Name ?? Singleton.EntityType().Name;
|
string typeName = NavigationSourceSegment.EntityType.Name;
|
||||||
items.Add(typeName);
|
items.Add(typeName);
|
||||||
items.Add(prefix + Utils.UpperFirstChar(identifier));
|
items.Add(prefix + Utils.UpperFirstChar(identifier));
|
||||||
}
|
}
|
||||||
|
@ -185,7 +174,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
/// <returns>The annotable element.</returns>
|
/// <returns>The annotable element.</returns>
|
||||||
protected IEdmVocabularyAnnotatable GetAnnotatableElement()
|
protected IEdmVocabularyAnnotatable GetAnnotatableElement()
|
||||||
{
|
{
|
||||||
IEdmEntityType entityType = EntitySet != null ? EntitySet.EntityType() : Singleton.EntityType();
|
IEdmEntityType entityType = NavigationSourceSegment.EntityType;
|
||||||
ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment);
|
ODataSegment lastSegmentProp = Path.Segments.LastOrDefault(c => c is ODataStreamPropertySegment);
|
||||||
|
|
||||||
if (lastSegmentProp == null)
|
if (lastSegmentProp == null)
|
||||||
|
@ -214,7 +203,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
|
|
||||||
private IEdmStructuralProperty GetStructuralProperty(IEdmEntityType entityType, string identifier)
|
private IEdmStructuralProperty GetStructuralProperty(IEdmEntityType entityType, string identifier)
|
||||||
{
|
{
|
||||||
return entityType.DeclaredStructuralProperties().FirstOrDefault(x => x.Name.Equals(identifier));
|
return entityType.StructuralProperties().FirstOrDefault(x => x.Name.Equals(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEdmNavigationProperty GetNavigationProperty(IEdmEntityType entityType, string identifier)
|
private IEdmNavigationProperty GetNavigationProperty(IEdmEntityType entityType, string identifier)
|
||||||
|
|
|
@ -26,15 +26,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
protected override void SetBasicInfo(OpenApiOperation operation)
|
protected override void SetBasicInfo(OpenApiOperation operation)
|
||||||
{
|
{
|
||||||
// Summary
|
// Summary
|
||||||
if (IsNavigationPropertyPath)
|
operation.Summary = IsNavigationPropertyPath
|
||||||
{
|
? $"Update media content for the navigation property {NavigationProperty.Name} in {NavigationSource.Name}"
|
||||||
operation.Summary = $"Update media content for the navigation property {NavigationProperty.Name} in {NavigationSource.Name}";
|
: $"Update media content for {NavigationSourceSegment.EntityType.Name} in {NavigationSourceSegment.Identifier}";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string typeName = EntitySet.EntityType().Name;
|
|
||||||
operation.Summary = $"Update media content for {typeName} in {EntitySet.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
// Description
|
||||||
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
|
IEdmVocabularyAnnotatable annotatableElement = GetAnnotatableElement();
|
||||||
|
@ -79,9 +73,8 @@ namespace Microsoft.OpenApi.OData.Operation
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override void SetSecurity(OpenApiOperation operation)
|
protected override void SetSecurity(OpenApiOperation operation)
|
||||||
{
|
{
|
||||||
UpdateRestrictionsType update = EntitySet != null
|
IEdmVocabularyAnnotatable annotatableNavigationSource = (IEdmVocabularyAnnotatable)NavigationSourceSegment.NavigationSource;
|
||||||
? Context.Model.GetRecord<UpdateRestrictionsType>(EntitySet, CapabilitiesConstants.UpdateRestrictions)
|
UpdateRestrictionsType update = Context.Model.GetRecord<UpdateRestrictionsType>(annotatableNavigationSource, CapabilitiesConstants.UpdateRestrictions);
|
||||||
: Context.Model.GetRecord<UpdateRestrictionsType>(Singleton, CapabilitiesConstants.UpdateRestrictions);
|
|
||||||
if (update == null || update.Permissions == null)
|
if (update == null || update.Permissions == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -450,41 +450,52 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(true, "Logo")]
|
[InlineData(true, "logo")]
|
||||||
[InlineData(false, "Logo")]
|
[InlineData(false, "logo")]
|
||||||
[InlineData(true, "Content")]
|
[InlineData(true, "content")]
|
||||||
[InlineData(false, "Content")]
|
[InlineData(false, "content")]
|
||||||
public void GetPathsWithStreamPropertyAndWithEntityHasStreamWorks(bool hasStream, string streamPropName)
|
public void GetPathsWithStreamPropertyAndWithEntityHasStreamWorks(bool hasStream, string streamPropName)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
IEdmModel model = GetEdmModel(hasStream, streamPropName);
|
IEdmModel model = GetEdmModel(hasStream, streamPropName);
|
||||||
ODataPathProvider provider = new ODataPathProvider();
|
ODataPathProvider provider = new ODataPathProvider();
|
||||||
var settings = new OpenApiConvertSettings();
|
var settings = new OpenApiConvertSettings();
|
||||||
|
const string TodosContentPath = "/todos({id})/content";
|
||||||
|
const string TodosValuePath = "/todos({id})/$value";
|
||||||
|
const string TodosLogoPath = "/todos({id})/logo";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var paths = provider.GetPaths(model,settings);
|
var paths = provider.GetPaths(model, settings);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(paths);
|
Assert.NotNull(paths);
|
||||||
|
Assert.Contains("/catalog/content", paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.Contains("/catalog/thumbnailPhoto", paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.Contains("/me/photo/$value", paths.Select(p => p.GetPathItemName()));
|
||||||
|
|
||||||
if (hasStream && !streamPropName.Equals("Content", StringComparison.OrdinalIgnoreCase))
|
if (streamPropName.Equals("logo"))
|
||||||
{
|
{
|
||||||
Assert.Equal(7, paths.Count());
|
if (hasStream)
|
||||||
Assert.Equal(new[] { "/me", "/me/photo", "/me/photo/$value", "/Todos", "/Todos({Id})", "/Todos({Id})/$value", "/Todos({Id})/Logo" },
|
{
|
||||||
paths.Select(p => p.GetPathItemName()));
|
Assert.Equal(12, paths.Count());
|
||||||
|
Assert.Contains(TodosValuePath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.Contains(TodosLogoPath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.DoesNotContain(TodosContentPath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(11, paths.Count());
|
||||||
|
Assert.Contains(TodosLogoPath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.DoesNotContain(TodosContentPath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
Assert.DoesNotContain(TodosValuePath, paths.Select(p => p.GetPathItemName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((hasStream && streamPropName.Equals("Content", StringComparison.OrdinalIgnoreCase)) ||
|
else if (streamPropName.Equals("content"))
|
||||||
(!hasStream && streamPropName.Equals("Content", StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
{
|
||||||
Assert.Equal(6, paths.Count());
|
Assert.Equal(11, paths.Count());
|
||||||
Assert.Equal(new[] { "/me", "/me/photo", "/me/photo/$value", "/Todos", "/Todos({Id})", "/Todos({Id})/Content" },
|
Assert.Contains(TodosContentPath, paths.Select(p => p.GetPathItemName()));
|
||||||
paths.Select(p => p.GetPathItemName()));
|
Assert.DoesNotContain(TodosLogoPath, paths.Select(p => p.GetPathItemName()));
|
||||||
}
|
Assert.DoesNotContain(TodosValuePath, paths.Select(p => p.GetPathItemName()));
|
||||||
else // !hasStream && !streamPropName.Equals("Content")
|
|
||||||
{
|
|
||||||
Assert.Equal(6, paths.Count());
|
|
||||||
Assert.Equal(new[] { "/me", "/me/photo", "/me/photo/$value", "/Todos", "/Todos({Id})", "/Todos({Id})/Logo"},
|
|
||||||
paths.Select(p => p.GetPathItemName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,13 +587,13 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
||||||
string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||||
<edmx:DataServices>
|
<edmx:DataServices>
|
||||||
<Schema Namespace=""microsoft.graph"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
<Schema Namespace=""microsoft.graph"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||||
<EntityType Name=""Todo"" HasStream=""{0}"">
|
<EntityType Name=""todo"" HasStream=""{0}"">
|
||||||
<Key>
|
<Key>
|
||||||
<PropertyRef Name=""Id"" />
|
<PropertyRef Name=""id"" />
|
||||||
</Key>
|
</Key>
|
||||||
<Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
|
<Property Name=""id"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||||
<Property Name=""{1}"" Type=""Edm.Stream""/>
|
<Property Name=""{1}"" Type=""Edm.Stream""/>
|
||||||
<Property Name = ""Description"" Type = ""Edm.String"" />
|
<Property Name = ""description"" Type = ""Edm.String"" />
|
||||||
</EntityType>
|
</EntityType>
|
||||||
<EntityType Name=""user"" OpenType=""true"">
|
<EntityType Name=""user"" OpenType=""true"">
|
||||||
<NavigationProperty Name = ""photo"" Type = ""microsoft.graph.profilePhoto"" ContainsTarget = ""true"" />
|
<NavigationProperty Name = ""photo"" Type = ""microsoft.graph.profilePhoto"" ContainsTarget = ""true"" />
|
||||||
|
@ -591,9 +602,17 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
||||||
<Property Name = ""height"" Type = ""Edm.Int32"" />
|
<Property Name = ""height"" Type = ""Edm.Int32"" />
|
||||||
<Property Name = ""width"" Type = ""Edm.Int32"" />
|
<Property Name = ""width"" Type = ""Edm.Int32"" />
|
||||||
</EntityType >
|
</EntityType >
|
||||||
|
<EntityType Name=""document"">
|
||||||
|
<Property Name=""content"" Type=""Edm.Stream""/>
|
||||||
|
<Property Name=""thumbnailPhoto"" Type=""Edm.Stream""/>
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name=""catalog"" BaseType=""microsoft.graph.document"">
|
||||||
|
<NavigationProperty Name=""reports"" Type = ""Collection(microsoft.graph.report)"" />
|
||||||
|
</EntityType>
|
||||||
<EntityContainer Name =""GraphService"">
|
<EntityContainer Name =""GraphService"">
|
||||||
<EntitySet Name=""Todos"" EntityType=""microsoft.graph.Todo"" />
|
<EntitySet Name=""todos"" EntityType=""microsoft.graph.todo"" />
|
||||||
<Singleton Name=""me"" Type=""microsoft.graph.user"" />
|
<Singleton Name=""me"" Type=""microsoft.graph.user"" />
|
||||||
|
<Singleton Name=""catalog"" Type=""microsoft.graph.catalog"" />
|
||||||
</EntityContainer>
|
</EntityContainer>
|
||||||
</Schema>
|
</Schema>
|
||||||
</edmx:DataServices>
|
</edmx:DataServices>
|
||||||
|
|
|
@ -55,13 +55,13 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||||
Assert.NotNull(me);
|
Assert.NotNull(me);
|
||||||
|
|
||||||
IEdmEntityType todo = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Todo");
|
IEdmEntityType todo = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Todo");
|
||||||
IEdmStructuralProperty sp = todo.DeclaredStructuralProperties().First(c => c.Name == "Logo");
|
IEdmStructuralProperty sp = todo.StructuralProperties().First(c => c.Name == "Logo");
|
||||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
|
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
|
||||||
new ODataKeySegment(todos.EntityType()),
|
new ODataKeySegment(todos.EntityType()),
|
||||||
new ODataStreamPropertySegment(sp.Name));
|
new ODataStreamPropertySegment(sp.Name));
|
||||||
|
|
||||||
IEdmEntityType user = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "user");
|
IEdmEntityType user = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "user");
|
||||||
IEdmNavigationProperty navProperty = user.DeclaredNavigationProperties().First(c => c.Name == "photo");
|
IEdmNavigationProperty navProperty = user.NavigationProperties().First(c => c.Name == "photo");
|
||||||
ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
|
ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
|
||||||
new ODataNavigationPropertySegment(navProperty),
|
new ODataNavigationPropertySegment(navProperty),
|
||||||
new ODataStreamContentSegment());
|
new ODataStreamContentSegment());
|
||||||
|
|
|
@ -52,13 +52,13 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||||
Assert.NotNull(todos);
|
Assert.NotNull(todos);
|
||||||
|
|
||||||
IEdmEntityType todo = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Todo");
|
IEdmEntityType todo = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Todo");
|
||||||
IEdmStructuralProperty sp = todo.DeclaredStructuralProperties().First(c => c.Name == "Logo");
|
IEdmStructuralProperty sp = todo.StructuralProperties().First(c => c.Name == "Logo");
|
||||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
|
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
|
||||||
new ODataKeySegment(todos.EntityType()),
|
new ODataKeySegment(todos.EntityType()),
|
||||||
new ODataStreamPropertySegment(sp.Name));
|
new ODataStreamPropertySegment(sp.Name));
|
||||||
|
|
||||||
IEdmEntityType user = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "user");
|
IEdmEntityType user = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "user");
|
||||||
IEdmNavigationProperty navProperty = user.DeclaredNavigationProperties().First(c => c.Name == "photo");
|
IEdmNavigationProperty navProperty = user.NavigationProperties().First(c => c.Name == "photo");
|
||||||
ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
|
ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
|
||||||
new ODataNavigationPropertySegment(navProperty),
|
new ODataNavigationPropertySegment(navProperty),
|
||||||
new ODataStreamContentSegment());
|
new ODataStreamContentSegment());
|
||||||
|
|
Loading…
Reference in a new issue