private void LoadRelatedPostProcess <T>( IEnumerable <T> sourceEntities, LoadRelatedOptions options, LoadRelatedPreProcessInfo preProcessInfo) { JToken[] rows = ClientAdaper.GetDocuments(preProcessInfo.EntityIdsToLoad); EntitiesProcessResult processResult = Process(rows, new OdmViewProcessingOptions()); Dictionary <string, EntitiesProcessResult> viewsSelectResult = SelectToManyFromViews(preProcessInfo); foreach (T sourceEntity in sourceEntities) { string entityId = GetEntityInstanceId(sourceEntity); JToken document = DocumentManager.DocInfo(entityId).Document; // ToOne foreach (PropertyInfo toOneProp in options.ToOne) { string relatedEntityId = GetRelatedToOneEntityId(document, toOneProp); object relatedToOneEntity = processResult.GetEntity(relatedEntityId); // This line was comment out because it is possible to get null related entity // when the property is optional. This check needs to be done only for required properties. //if (relatedToOneEntity == null) throw new Exception("Fail to find ToOne related entity for property " + toOneProp); toOneProp.SetValue(sourceEntity, relatedToOneEntity); } // ToOne already loaded foreach (PropertyInfo toOneProp in options.ToOneExist) { string relatedEntityId = GetRelatedToOneEntityId(document, toOneProp); object relatedToOneEntity = identityMap.GetEntityById(relatedEntityId); if (relatedToOneEntity == null) { throw new Exception("Fail to find ToOneExist related entity for property " + toOneProp); } toOneProp.SetValue(sourceEntity, relatedToOneEntity); } // ToMany Direct foreach (PropertyInfo toManyDirectProp in options.ToManyDirect) { string[] relatedEntitiesIds = GetRelatedToManyEntitiesIds(document, toManyDirectProp); if (relatedEntitiesIds != null) { serializer.SetDirectAssoicationCollectionProperty(sourceEntity, toManyDirectProp, relatedEntitiesIds); } } // ToMany Inverse foreach (LoadRelatedWithViewInfo toManyViewInfo in options.ToManyView) { EntitiesProcessResult viewProcessResult = viewsSelectResult[toManyViewInfo.ViewName]; string[] relatedEntitiesIds = viewProcessResult.GetRelatedEntitiesIds(entityId); AssociationAttribute associationAttr = AssociationAttribute.GetSingle(toManyViewInfo.PropertyInfo); serializer.SetInverseAssociationCollectionInternal( sourceEntity, toManyViewInfo.PropertyInfo, associationAttr, relatedEntitiesIds); } } }
/// <summary> /// Load specified related entities of the sourceEntities. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sourceEntities"></param> /// <param name="configOptions"></param> public void LoadRelated <T>(IEnumerable <T> sourceEntities, Action <LoadRelatedOptionsBuilder <T> > configOptions) { var optionsBuilder = new LoadRelatedOptionsBuilder <T>(); configOptions(optionsBuilder); LoadRelatedOptions options = optionsBuilder.Build(); // First pre-process all the source entities and find the relatd entities to load. LoadRelatedPreProcessInfo preProcessInfo = LoadRelatedPreProcess(sourceEntities, options); // Load the related entities and set the association properties. LoadRelatedPostProcess(sourceEntities, options, preProcessInfo); }
private Dictionary <string, EntitiesProcessResult> SelectToManyFromViews(LoadRelatedPreProcessInfo preProcessInfo) { var viewSelectResult = new Dictionary <string, EntitiesProcessResult>(); foreach (KeyValuePair <string, string[]> viewSelectionInfo in preProcessInfo.ViewsToSelect) { CouchViewOptions viewOptions = new CouchViewOptions { IncludeDocs = true, Keys = viewSelectionInfo.Value.Cast <object>().ToList() }; JToken[] rows = clientAdapter.GetViewRows(viewSelectionInfo.Key, viewOptions); EntitiesProcessResult processResult = Process(rows, new OdmViewProcessingOptions()); viewSelectResult.Add(viewSelectionInfo.Key, processResult); } return(viewSelectResult); }