@@ -222,6 +222,10 @@ $data.Class.define('$data.StorageProviderBase', null, null,
222222 keyProperties = [ memDef . keys ] ;
223223 } else if ( memDef && Array . isArray ( memDef . keys ) ) {
224224 keyProperties = [ ] . concat ( memDef . keys ) ;
225+ } else if ( memDef && typeof memDef . foreignKeys === "string" && memDef . foreignKeys ) {
226+ keyProperties = [ memDef . foreignKeys ] ;
227+ } else if ( memDef && Array . isArray ( memDef . foreignKeys ) ) {
228+ keyProperties = [ ] . concat ( memDef . foreignKeys ) ;
225229 }
226230
227231 association . ReferentialConstraint = association . ReferentialConstraint || [ ] ;
@@ -255,8 +259,29 @@ $data.Class.define('$data.StorageProviderBase', null, null,
255259 complexType . ReferentialConstraint = complexType . ReferentialConstraint || [ ] ;
256260
257261 complexType . ToType . memberDefinitions . getPublicMappedProperties ( ) . forEach ( function ( d ) {
258- instanceDefinition [ complexType . FromPropertyName + '__' + d . name ] = buildDbType_copyPropertyDefinition ( d ) ;
259- complexType . ReferentialConstraint . push ( buildDbType_createConstrain ( complexType . ToType , complexType . FromType , d . name , complexType . FromPropertyName ) ) ;
262+ if ( d . inverseProperty ) {
263+ var type = Container . resolveType ( d . type ) ;
264+ if ( type . isAssignableTo && type . isAssignableTo ( $data . Entity ) ) {
265+ var keyProp = type . memberDefinitions . getPublicMappedProperties ( ) . filter ( function ( p ) { return p . key } ) [ 0 ] ;
266+
267+ var keyPropName = ( d . keys && d . keys [ 0 ] ) || d . name + '__' + keyProp . name ;
268+
269+ if ( ! instanceDefinition [ complexType . FromPropertyName + '__' + keyPropName ] ) {
270+ instanceDefinition [ complexType . FromPropertyName + '__' + keyPropName ] = buildDbType_copyPropertyDefinition ( keyProp ) ;
271+ }
272+
273+ var constraint = { complexNavProperty : true } ;
274+ constraint [ complexType . ToType . name ] = d . name + '.' + keyProp . name ;
275+ constraint [ complexType . FromType . name ] = complexType . FromPropertyName + '__' + keyPropName ;
276+ complexType . ReferentialConstraint . push ( constraint ) ;
277+ }
278+
279+ } else {
280+ instanceDefinition [ complexType . FromPropertyName + '__' + d . name ] = buildDbType_copyPropertyDefinition ( d ) ;
281+ instanceDefinition [ complexType . FromPropertyName + '__' + d . name ] . complexType = complexType ;
282+
283+ complexType . ReferentialConstraint . push ( buildDbType_createConstrain ( complexType . ToType , complexType . FromType , d . name , complexType . FromPropertyName ) ) ;
284+ }
260285 } , this ) ;
261286 } , this ) ;
262287 }
@@ -274,6 +299,33 @@ $data.Class.define('$data.StorageProviderBase', null, null,
274299 }
275300 } , this ) ;
276301
302+ var getProp = function ( container , path , throwWhenNoValue ) {
303+ var p = path . split ( "." ) ;
304+ var holder = container ;
305+ for ( var i = 0 ; i < p . length ; i ++ ) {
306+ holder = holder [ p [ i ] ] ;
307+ if ( ! holder ) {
308+ if ( throwWhenNoValue ) throw 'no value' ;
309+ return holder ;
310+ }
311+ }
312+
313+ return holder ;
314+ }
315+
316+ var setProp = function ( dbInstance , complexInstance , constrain , mapping ) {
317+ var value = dbInstance [ constrain [ mapping . From ] ] ;
318+ try {
319+ if ( ! constrain . complexNavProperty || typeof value === "undefined" ) {
320+ value = getProp ( complexInstance , constrain [ mapping . To ] , constrain . complexNavProperty ) ;
321+ }
322+ } catch ( e ) {
323+ return ;
324+ }
325+
326+ dbInstance [ constrain [ mapping . From ] ] = value ;
327+ }
328+
277329 if ( storageModel . Associations ) {
278330 storageModel . Associations . forEach ( function ( association ) {
279331 if ( ( association . FromMultiplicity == "*" && association . ToMultiplicity == "0..1" ) || ( association . FromMultiplicity == "0..1" && association . ToMultiplicity == "1" ) ) {
@@ -285,7 +337,7 @@ $data.Class.define('$data.StorageProviderBase', null, null,
285337 ( logicalEntity && ! logicalEntity . changedProperties ) ||
286338 ( logicalEntity && logicalEntity . changedProperties && ! logicalEntity . changedProperties . some ( function ( md ) { return md . name == constrain [ association . From ] ; } ) )
287339 ) ) {
288- dbInstance [ constrain [ association . From ] ] = complexInstance [ constrain [ association . To ] ] ;
340+ dbInstance [ constrain [ association . From ] ] = getProp ( complexInstance , constrain [ association . To ] ) ;
289341 } else if ( Guard . isNullOrUndefined ( logicalEntity [ constrain [ association . From ] ] ) ) {
290342 dbInstance [ constrain [ association . From ] ] = null ;
291343 }
@@ -299,8 +351,13 @@ $data.Class.define('$data.StorageProviderBase', null, null,
299351 var complexInstance = logicalEntity [ cmpType . FromPropertyName ] ;
300352 if ( complexInstance !== undefined ) {
301353 cmpType . ReferentialConstraint . forEach ( function ( constrain ) {
302- if ( complexInstance !== null ) {
303- dbInstance [ constrain [ cmpType . From ] ] = complexInstance [ constrain [ cmpType . To ] ] ;
354+ if ( complexInstance !== null &&
355+ (
356+ ( logicalEntity && ! logicalEntity . changedProperties ) ||
357+ ( logicalEntity && logicalEntity . changedProperties && ! logicalEntity . changedProperties . some ( function ( md ) { return md . name == constrain [ cmpType . From ] ; } ) )
358+ ) ) {
359+ setProp ( dbInstance , complexInstance , constrain , cmpType ) ;
360+ // dbInstance[constrain[cmpType.From]] = getProp(complexInstance, constrain[cmpType.To]);
304361 } else if ( Guard . isNullOrUndefined ( logicalEntity [ constrain [ association . From ] ] ) ) {
305362 dbInstance [ constrain [ cmpType . From ] ] = null ;
306363 }
0 commit comments