void IMapping.InnerApply(MappingContext c) { var context = (MappingContext <T>)c; // ....................... // GET ALL MAPPINGS List <IMapping> mappingsToApply = null; foreach (IMapping mapping in ((IMapping)this).GetAllMappings(includeBase: true)) { if (mappingsToApply == null) { mappingsToApply = new List <IMapping>(); } mappingsToApply.Add(mapping); } // ....................... // APPLY CHILD MAPPINGS Dictionary <IEntityProperty, object> propertyValues = null; bool hasChildMappings = false; // Apply current mappings for (int i = 0; i < mappingsToApply.Count; i++) { IMapping mapping = mappingsToApply[i]; // Ignore subquery mappings that aren't the current mapping if (mapping is ISubqueryMapping && context.CurrentSubquery.Mapping != mapping) { continue; } MappingContext currentContext = mapping is IChildMapping? mapping.CreateContext(context) : context; mapping.Apply(currentContext); if (context.DoBreak) { break; } if (mapping is IChildMapping) { // If a target has been specified, save it if (currentContext.IsTargetSet) { hasChildMappings = true; if (mapping is IPropertyMapping) { if (propertyValues == null) { propertyValues = new Dictionary <IEntityProperty, object>(); } var propertyMapping = (IPropertyMapping)mapping; propertyValues.Add(propertyMapping.Property, currentContext.Target); } else if (mapping is IVariableMapping) { var variableMapping = (IVariableMapping)mapping; context.SetVariable(variableMapping.Variable, currentContext.Target); } } } // There might be derived mappings at this point, find them if (i == mappingsToApply.Count - 1 && context.TargetType != null) { IEntityDefinition definition = this.EntitySpace.GetDefinition(context.TargetType); if (definition != null) { // TODO: better way to indicate which derived mapping to use - possibly by name IMapping derived = null; foreach (IMapping d in definition.Mappings.Where(m => m.BaseMapping == this)) { derived = d; break; } // Get all inherit if (derived != null) { mappingsToApply.AddRange(derived.GetAllMappings(includeBase: true, untilBase: typeof(T))); } } } } // ....................... // GET FROM CACHE bool isEntity = this.EntitySpace.GetDefinition <T>() != null; bool shouldCache = isEntity && this.CacheIdentity != null && propertyValues != null && this.CacheIdentity.HasValidValues(propertyValues); if (shouldCache) { Identity cacheId = this.CacheIdentity.IdentityFromValues(propertyValues); object val = context.Cache.Get <T>(cacheId); if (val != null) { // Update cache context.Target = (T)val; context.Cache.Update(this.CacheIdentity, propertyValues); shouldCache = false; } } // ....................... // INSTANTIATION // Instantiate target if it hasn't been specifically applied and there are sub mappings that have executed if (!context.IsTargetSet && hasChildMappings) { // Instantiate a new target context.Target = context.TargetType != null ? (T)Activator.CreateInstance(context.TargetType) : Activator.CreateInstance <T>(); } // ....................... // PUT IN CACHE if (context.IsTargetSet && propertyValues != null) { // Apply properties foreach (var propVal in propertyValues) { propVal.Key.SetValue(context.Target, propVal.Value); } // Add to cache if (shouldCache) { context.Cache.Put <T>(this.CacheIdentity, context.Target, propertyValues.Keys.ToArray()); } } }