Example #1
0
        private static BinderResult GetEntityGeneric <T>(IDbEntity entity, IEnumerable entities, string path, string collectionPath, string indexers)
            where T : class, IDbEntity
        {
            BinderResult result = null;

            IEnumerable <T> typedEntities = entities as IEnumerable <T>;

            string[] collectionEntityIndexers = indexers.Split(',');
            List <Tuple <string, object> > collectionEntityKeys = new List <Tuple <string, object> >();
            Type type = typeof(T);

            foreach (string indexer in collectionEntityIndexers)
            {
                string[] keyAndValue = indexer.Split('=');
                collectionEntityKeys.Add(new Tuple <string, object>(keyAndValue[0], Convert.ChangeType(keyAndValue[1], type.GetProperty(keyAndValue[0]).GetGetMethod().ReturnType, null)));
            }

            IDbEntity collectionEntity = typedEntities.AsQueryable().WherePrimaryKeysEqual(collectionEntityKeys.ToArray()).SingleOrDefault() as IDbEntity;
            string    actualPath       = path;

            if (collectionEntity != null)
            {
                actualPath = DbEntityUtilities.GenerateCollectionItemPath(collectionPath, collectionEntity.PrimaryKeys, collectionEntity.Guid);
            }
            result = new BinderResult(collectionEntity, path, actualPath);

            return(result);
        }
        public static void DepthFirst(IDbEntity entity,
                                      Type projectionType,
                                      string path,
                                      IDictionary <Type, ISet <string> > processedEntities,
                                      Action <IDbEntity, string> beforeRecursionAction,
                                      Action <IDbEntity, string, string, PropertyInfo> beforePropertyRecursionAction,
                                      Func <IDbEntity, IEnumerable <IDbEntity>, string, string, PropertyInfo, IEnumerable <IDbEntity> > beforeCollectionRecursionAction,
                                      Action <IDbEntity, IEnumerable <IDbEntity>, string, string, PropertyInfo> afterCollectionRecursionAction,
                                      Action <IDbEntity, string> afterRecursionAction)
        {
            bool processed = !processedEntities.Add(entity.GetType(), entity.Guid);

            if (processed)
            {
                // Prevents self-referencing entities from causing infinite loops
                return;
            }
            beforeRecursionAction(entity, path);

            IEnumerable <PropertyInfo> virtualProperties = entity.GetType().GetVirtualProperties(true, true);

            virtualProperties = virtualProperties.Where(ep => projectionType.GetProperties().Any(pp => ep.Name.Equals(pp.Name)));
            foreach (PropertyInfo property in virtualProperties)
            {
                PropertyInfo projectionProperty = projectionType.GetProperty(property.Name);
                //PropertyInfo projectionProperty = property;
                string propertyPath = DbEntityUtilities.GeneratePropertyPath(path, property.Name);
                beforePropertyRecursionAction(entity, path, propertyPath, property);

                object value = property.GetGetMethod().Invoke(entity, _emptyObjectArray);
                if (value != null)
                {
                    if (property.GetGetMethod().ReturnType.IsIEnumerable() &&
                        DbEntityUtilities.IsIDbEntity(property.GetGetMethod().ReturnType.GetGenericArguments()[0]))
                    {
                        IEnumerable <IDbEntity> entities = value as IEnumerable <IDbEntity>;
                        entities = beforeCollectionRecursionAction(entity, entities, path, propertyPath, property);

                        for (int i = 0; i < entities.Count(); i++)
                        {
                            DepthFirst(entities.ElementAt(i), projectionProperty.GetGetMethod().ReturnType.GetGenericArguments()[0], DbEntityUtilities.GenerateCollectionItemPath(propertyPath, entities.ElementAt(i).Guid), processedEntities, beforeRecursionAction, beforePropertyRecursionAction, beforeCollectionRecursionAction, afterCollectionRecursionAction, afterRecursionAction);
                        }

                        afterCollectionRecursionAction(entity, entities, path, propertyPath, property);
                    }
                    else if (DbEntityUtilities.IsIDbEntity(property.GetGetMethod().ReturnType))
                    {
                        DepthFirst(value as IDbEntity, projectionProperty.GetGetMethod().ReturnType, propertyPath, processedEntities, beforeRecursionAction, beforePropertyRecursionAction, beforeCollectionRecursionAction, afterCollectionRecursionAction, afterRecursionAction);
                    }
                }
            }

            afterRecursionAction(entity, path);
        }