Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
miltonc
Product and Topic Expert
Product and Topic Expert
0 Kudos

Complex Type in SMP SDK

At the core of OData are feeds, which are Collections of typed Entries. Each entry represents a structured record with a key that has a list of Properties of primitive or complex types.  Complex Types are structured types also consisting of a list of properties but with no key, and thus can only exist as a property of a containing entity or as a temporary value.  For example the following URI represents a feed of Supplier entries: http://services.odata.org/OData/OData.svc/Suppliers.

To address an entity property clients append a path segment containing property name to the URL of the entity. If the property has a complex type, properties of that value can be addressed by further property name composition.

First let's take a look at how to get a simple property. The request below returns the Name property of a Supplier.

GET serviceRoot/Suppliers(0)/Name

Then let's see how to get a property value of a complex type. The request below returns the Street of the complex type Address in a Supplier.

GET serviceRoot/Suppliers(0)/Address/Street

How do we do this in SMP SDK ?

It’s fairly easy to get the value of a complex type using SMP SDK.  It pretty much follows the same paradigm outlined above.  The following snippet of code is used to get the values of a complex type.

var store = new ODataStore("http://services.odata.org/V3/OData/OData.svc/", new ODataStore.StoreOptions()); 

await store.OpenAsync();

var execution = store.ScheduleReadEntitySet("Suppliers");

var response = await execution.Response;

var entities = (ODataEntitySet)((IODataResponseSingle)response).Payload;

Console.WriteLine("Street: " + entities[0].Properties["Address/Street"].Value);

Console.WriteLine("City: " + entities [0].Properties["Address/City"].Value);

Console.WriteLine("State: " + entities [0].Properties["Address/State"].Value);

Console.WriteLine("ZipCode: " + entities [0].Properties["Address/ZipCode"].Value);

Console.WriteLine("Country:" + entities [0].Properties["Address/Country"].Value);

How about CREATE in SMP SDK ?

The same syntax can also be used for CREATE operations.  Make sure to use the full access (Read-Write) of the OData Service found under http://services.odata.org.  The following snippet of code is used to CREATE an entity containing a complex type.

var entity = new SAP.Data.OData.Online.ODataEntity("ODataDemo.Supplier");

store.AllocateProperties(entity, SAP.Data.OData.Store.PropertyCreationMode.All);

entity.Properties["ID"].Value = 101;

entity.Properties["Name"].Value = "Unit Test Supplier";

entity.Properties["Address/Street"].Value = "Unit Test Street";

entity.Properties["Address/City"].Value = "Unit Test City";

entity.Properties["Address/State"].Value = "GA";

entity.Properties["Address/ZipCode"].Value = "55555";

entity.Properties["Address/Country"].Value = "USA";

entity.Properties["Concurrency"].Value = 1;

execution = store.ScheduleCreateEntity(entity, "Suppliers");

await execution.Response;

How about UPDATE in SMP SDK ?

The same syntax can also be used for UPDATE operations.  Make sure to use the full access (Read-Write) of the OData Service found under http://services.odata.org.  The following snippet of code is used to UPDATE an entity containing a complex type.

var execution = store.ScheduleReadEntitySet("Suppliers");

var response = await execution.Response;

var entities = (ODataEntitySet)((IODataResponseSingle)response).Payload;

var entity = entities.Last();

entity.Properties["Address/Street"].Value = "New Street";

execution = store.ScheduleUpdateEntity(entity);

await execution.Response;

Here is the corresponding syntax in Objective-C.  Notice that in Objective-C, the syntax is slightly different.  To properly set a complex type value in Objective-C, you assign an NSDictionary as the SODataProperty value.  The SMP SDK automatically computes that it’s a complex type when the value is an NSDictionary.

CREATE:

NSMutableDictionary *complexProperty = [NSMutableDictionary dictionaryWithCapacity:5];

id<SODataProperty> prop1 = [[SODataPropertyDefault alloc] initWithName:@"Street"];

prop1.value = @"Unit Test Street";

complexProperty[@"Street"] = prop1;

id<SODataProperty> prop2 = [[SODataPropertyDefault alloc] initWithName:@"City"];

prop2.value = @"Unit Test City";

complexProperty[@"City"] = prop2;

id<SODataProperty> prop3 = [[SODataPropertyDefault alloc] initWithName:@"State"];

prop3.value = @"GA";

complexProperty[@"State"] = prop3;

id<SODataProperty> prop4 = [[SODataPropertyDefault alloc] initWithName:@"ZipCode"];

prop4.value = @"30022";

complexProperty[@"ZipCode"] = prop4;

id<SODataProperty> prop5 = [[SODataPropertyDefault alloc] initWithName:@"Country"];

prop5.value = @"USA";

complexProperty[@"Country"] = prop5;

prop = [[SODataPropertyDefault alloc] initWithName:@"Address"];

prop.value = complexProperty;

UPDATE:

NSDictionary* entityProperties = entity.properties;

id<SODataProperty> complexProperty = entityProperties[@“Address"];

if (complexProperty.isComplex) {

       NSDictionary* propertyDictionary = (NSDictionary*)complexProperty.value;

   id<SODataProperty> property1 = propertyDictionary[@“Street"];

   property1.value = @“Some new street";

}

GET:

NSDictionary *complexProperty = (NSDictionary *)[(id<SODataProperty>)entity.properties[@"Address"] value];

NSString *property1 = (NSString *) [(id<SODataProperty>)complexProperty[@“Street"] value];

Please find attached the source code for a sample Windows application that submits GET, INSERT and UPDATE requests on an entity containing complex types. 

In the next blog, I will be talking about deep inserts.