public virtual ActionResult MultipleSelector(int page = 1, string parentpath = null, Guid?parentid = null)
        {
            if (!User.Identity.IsAuthenticated && !Metadata.AllowAnonymous)
            {
                return(new HttpStatusCodeResult(403));
            }
            if (!Metadata.ViewRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            IQueryable <TEntity> queryable = EntityQueryable.Query();

            if (parentpath != null && parentid.HasValue)
            {
                try
                {
                    queryable = EntityQueryable.InParent(queryable, parentpath, parentid.Value);
                }
                catch
                {
                    return(new HttpStatusCodeResult(400));
                }
            }
            var model = new EntityViewModel <TEntity>(EntityQueryable.OrderBy(queryable), page, 10);

            if (Metadata.ParentProperty != null)
            {
                model.Parent = GetParentModel(parentid, 3);
            }
            model.Headers = Metadata.ViewProperties;
            model.UpdateItems();
            return(View(model));
        }
        public virtual EntityViewer GetViewer <TEntity>() where TEntity : class, IEntity, new()
        {
            IEntityQueryable <TEntity> context = EntityBuilder.GetContext <TEntity>();

            EntityMetadata metadata = EntityAnalyzer.GetMetadata <TEntity>();

            EntityViewModel <TEntity> model = new EntityViewModel <TEntity>(context.OrderBy());

            model.Headers = metadata.ViewProperties;
            model.UpdateItems();

            EntityViewer viewer = new EntityViewer(this);

            viewer.Model = model;

            WpfViewButton createButton = new WpfViewButton();

            createButton.Name    = "Create";
            createButton.Command = new EntityCommand(new EntityCommand.ExecuteDelegate(t =>
            {
                viewer.NavigationService.Navigate(GetEditor <TEntity>(context.Create()));
            }));
            model.Buttons = new EntityViewButton[] { createButton };

            return(viewer);
        }
        public virtual ActionResult Index(int page = 1, int size = 20, string parentpath = null, Guid?parentid = null, bool search = false)
        {
            if (page < 1)
            {
                return(new HttpStatusCodeResult(400));
            }
            if (size < 1)
            {
                return(new HttpStatusCodeResult(400));
            }
            if (!Metadata.ViewRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            IQueryable <TEntity>    queryable   = EntityQueryable.Query();
            List <EntitySearchItem> searchItems = new List <EntitySearchItem>();

            if (search)
            {
                var keys = Request.QueryString.AllKeys.Where(t => t.StartsWith("Search.")).Select(t => t.Substring(7).Split('.')).GroupBy(t => t[0], t => t.Length == 1 ? "" : "." + t[1]).ToArray();
                for (int i = 0; i < keys.Length; i++)
                {
                    string           propertyName = keys[i].Key;
                    PropertyMetadata property     = Metadata.GetProperty(propertyName);
                    if (property == null || !property.Searchable)
                    {
                        continue;
                    }
                    EntitySearchItem searchItem = new EntitySearchItem();
                    string[]         options    = keys[i].ToArray();
                    switch (property.Type)
                    {
                    case ComponentModel.DataAnnotations.CustomDataType.Date:
                    case ComponentModel.DataAnnotations.CustomDataType.DateTime:
                        for (int a = 0; a < options.Length; a++)
                        {
                            if (options[a] == ".Start")
                            {
                                DateTime start;
                                if (!DateTime.TryParse(Request.QueryString["Search." + keys[i].Key + options[a]], out start))
                                {
                                    continue;
                                }
                                searchItem.MorethanDate = start;
                                ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                                queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.GreaterThanOrEqual(Expression.Property(parameter, property.Property), Expression.Constant(start)), parameter));
                            }
                            else if (options[a] == ".End")
                            {
                                DateTime end;
                                if (!DateTime.TryParse(Request.QueryString["Search." + keys[i].Key + options[a]], out end))
                                {
                                    continue;
                                }
                                searchItem.LessthanDate = end;
                                ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                                queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.LessThanOrEqual(Expression.Property(parameter, property.Property), Expression.Constant(end)), parameter));
                            }
                        }
                        break;

                    case ComponentModel.DataAnnotations.CustomDataType.Boolean:
                    case ComponentModel.DataAnnotations.CustomDataType.Sex:
                        if (options[0] == "")
                        {
                            bool result;
                            if (!bool.TryParse(Request.QueryString["Search." + keys[i].Key], out result))
                            {
                                continue;
                            }
                            searchItem.Equal = result;
                            ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                            queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.Equal(Expression.Property(parameter, property.Property), Expression.Constant(result)), parameter));
                        }
                        break;

                    case ComponentModel.DataAnnotations.CustomDataType.Currency:
                    case ComponentModel.DataAnnotations.CustomDataType.Integer:
                    case ComponentModel.DataAnnotations.CustomDataType.Number:
                        for (int a = 0; a < options.Length; a++)
                        {
                            if (options[a] == ".Start")
                            {
                                double start;
                                if (!double.TryParse(Request.QueryString["Search." + keys[i].Key + options[a]], out start))
                                {
                                    continue;
                                }
                                searchItem.Morethan = start;
                                ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                                queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.GreaterThanOrEqual(Expression.Property(parameter, property.Property), Expression.Constant(start)), parameter));
                            }
                            else if (options[a] == ".End")
                            {
                                double end;
                                if (!double.TryParse(Request.QueryString["Search." + keys[i].Key + options[a]], out end))
                                {
                                    continue;
                                }
                                searchItem.Lessthan = end;
                                ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                                queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.LessThanOrEqual(Expression.Property(parameter, property.Property), Expression.Constant(end)), parameter));
                            }
                        }
                        break;

                    case ComponentModel.DataAnnotations.CustomDataType.Other:
                        if (property.CustomType == "Enum")
                        {
                            object result;
                            try
                            {
                                result = Enum.Parse(property.Property.PropertyType, Request.QueryString["Search." + keys[i].Key]);
                            }
                            catch
                            {
                                continue;
                            }
                            searchItem.Enum = new EnumConverter(property.Property.PropertyType).ConvertToString(result);
                            ParameterExpression parameter = Expression.Parameter(Metadata.Type);
                            queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.Equal(Expression.Property(parameter, property.Property), Expression.Constant(result)), parameter));
                        }
                        else if (property.CustomType == "Entity")
                        {
                            searchItem.Contains = Request.QueryString["Search." + keys[i].Key];
                            ParameterExpression parameter  = Expression.Parameter(Metadata.Type);
                            Expression          expression = Expression.Property(Expression.Property(parameter, property.Property), EntityAnalyzer.GetMetadata(property.Property.PropertyType).DisplayProperty.Property);
                            expression = Expression.Call(expression, typeof(string).GetMethod("Contains"), Expression.Constant(searchItem.Contains));
                            queryable  = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(expression, parameter));
                        }
                        break;

                    default:
                        if (property.Property.PropertyType == typeof(string))
                        {
                            searchItem.Contains = Request.QueryString["Search." + keys[i].Key];
                            ParameterExpression parameter  = Expression.Parameter(Metadata.Type);
                            Expression          expression = Expression.Property(parameter, property.Property);
                            expression = Expression.Call(expression, typeof(string).GetMethod("Contains"), Expression.Constant(searchItem.Contains));
                            queryable  = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(expression, parameter));
                        }
                        break;
                    }
                    if (searchItem.Contains != null || searchItem.Enum != null || searchItem.Equal.HasValue || searchItem.Lessthan.HasValue || searchItem.LessthanDate.HasValue || searchItem.Morethan.HasValue || searchItem.MorethanDate.HasValue)
                    {
                        searchItem.Name = property.Name;
                    }
                    if (searchItem.Name != null)
                    {
                        searchItems.Add(searchItem);
                    }
                }
            }
            else
            {
                if (parentpath != null && parentid.HasValue)
                {
                    try
                    {
                        queryable = EntityQueryable.InParent(queryable, parentpath, parentid.Value);
                    }
                    catch
                    {
                        return(new HttpStatusCodeResult(400));
                    }
                }
            }
            var model = new EntityViewModel <TEntity>(EntityQueryable.OrderBy(queryable), page, size);

            if (Metadata.ParentProperty != null && !search)
            {
                model.Parent = GetParentModel(parentid, Metadata.ParentLevel);
            }
            model.SearchItem     = searchItems.ToArray();
            model.Headers        = Metadata.ViewProperties;
            model.PageSizeOption = PageSize;
            model.UpdateItems();

            return(View(model));
        }