OData / AspNetCoreOData

ASP.NET Core OData: A server library built upon ODataLib and ASP.NET Core
Other
458 stars 158 forks source link

How to configure a Property in a parent class for a Property of a nested Owned class directly? #1339

Open ptrushin opened 2 weeks ago

ptrushin commented 2 weeks ago

I have

[Owned]
public class Properties
{
public string Property1 {get;set;}
}

public class Main
{
public Properties Properties {get;set;}
...
}

And I want to configure Property1 as Main class property with name Ware. When i try

builder.EntityType<Main>().Property(e => e.Properties.Property1).Name = "Ware";

i get an exception 'MemberExpressions must be bound to the LambdaExpression parameter.'

How can i do this?

xuzhg commented 2 weeks ago

Did you try:

builder.ComplexType<Properties>().Property(e => e.Property1).Name = "Ware";

ptrushin commented 2 weeks ago

Yes i did, result was {"properties":{"ware":"ware1"}} but i want the result {"ware": "ware1"} without inner object properties

xuzhg commented 2 weeks ago

I think you can do like this:

If you can change your model

a) Add a new property as follows

public class Main
{
public Properties Properties {get;set;}
+ public string Ware {
+       get => Properties.Property1;
+       set => Properties.Property1 = value;
+ }
...
}

b) Ignore the 'Properties' builder.EntityType<Main>().IgnoreProperty(e => e.Properties);

If you cannot change your model:

a) Ignore the 'Properties', same as above b) Create a new EdmProperty for Edm Type 'Main'.

var builder = ....
EdmModel model = builder.GetEdmModel() as EdmModel;
var mainType = model.SchemaElements.OfType<EdmEntityType>().First(c => c.Name == "Main") as EdmEntityType;
var wareProperty = mainType.AddStructuralProperty("Ware", EdmCoreMode.Instance.GetString(false));
PropertyInfo propert1Info = typeof(Properties).GetProperty("Property1");
model.SetAnnotationValue(wareProperty, new ClrPropertyInfoAnnotation(property1Info));

Some function names maybe not correct. Please let me know if it cannot work.

ptrushin commented 2 weeks ago

Thanks. I need second variant, because i dont know property name in compile time. But with your example i get an exception

System.InvalidOperationException: The EDM instance of type '[Main Nullable=True]' is missing the property 'Ware'.

@xuzhg

xuzhg commented 1 week ago

Thanks. I need second variant, because i dont know property name in compile time. But with your example i get an exception

System.InvalidOperationException: The EDM instance of type '[Main Nullable=True]' is missing the property 'Ware'.

@xuzhg

can you share your repro?

ptrushin commented 1 week ago

@xuzhg , example - https://github.com/ptrushin/odata-text 1) when /odata/$metadata - all ok 2) but when i try to get data - /odata/Main - i get an exception The EDM instance of type '[OdataText.Main Nullable=True]' is missing the property 'Ware'