/// <summary> /// Get the action result of index page. /// </summary> /// <param name="modelDelegate">Get index model delegate.</param> /// <param name="searchDelegate">Get search item delegate.</param> /// <param name="parentDelegate">Get parent model delegate.</param> /// <param name="page">Number of current page.</param> /// <param name="size">Number of entities per page.</param> /// <param name="parentpath">Path of parent for entity.</param> /// <param name="parentid">Parent id.</param> /// <param name="search">Is a search result.</param> /// <returns></returns> public async Task <ActionResult> GetIndexAction(GetIndexModelDelegate modelDelegate, GetSearchItemDelegate searchDelegate, GetParentModelDelegate parentDelegate, 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)); } IQueryable <TEntity> queryable = EntityContext.Query(); EntitySearchItem[] searchItems; if (search) { searchItems = searchDelegate(ref queryable); } else { searchItems = new EntitySearchItem[0]; if (parentpath != null && parentid.HasValue) { try { queryable = EntityContext.InParent(queryable, parentpath, parentid.Value); } catch { return(new HttpStatusCodeResult(400)); } } } var model = await modelDelegate(queryable, page, size); if (model == null) { return(new HttpStatusCodeResult(404)); } if (Metadata.ParentProperty != null && !search) { model.Parent = await parentDelegate(parentid); } model.SearchItem = searchItems; model.Items = await EntityContext.ToArrayAsync(model.Queryable.Skip((model.CurrentPage - 1) * model.CurrentSize).Take(model.CurrentSize)); if (model.ViewButtons.Length > 0) { IServiceProvider serviceProvider = Controller.GetServiceProvider(); foreach (var item in model.ViewButtons) { item.SetTarget(serviceProvider); } } return(GetView(model)); }
/// <summary> /// Get search item in request. /// </summary> /// <param name="queryable">Queryable of TEntity.</param> /// <returns>Search item of TEntity.</returns> public EntitySearchItem[] GetSearchItem(ref IQueryable <TEntity> queryable) { List <EntitySearchItem> searchItems = new List <EntitySearchItem>(); var keys = Controller.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; IPropertyMetadata 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(Controller.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.ClrName), Expression.Constant(start)), parameter)); } else if (options[a] == ".End") { DateTime end; if (!DateTime.TryParse(Controller.Request.QueryString["Search." + keys[i].Key + options[a]], out end)) { continue; } if (property.Type == CustomDataType.Date) { end = end.AddDays(1); } searchItem.LessthanDate = end; ParameterExpression parameter = Expression.Parameter(Metadata.Type); queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.LessThanOrEqual(Expression.Property(parameter, property.ClrName), Expression.Constant(end)), parameter)); } } break; case ComponentModel.DataAnnotations.CustomDataType.Boolean: case ComponentModel.DataAnnotations.CustomDataType.Sex: if (options[0] == "") { bool result; if (!bool.TryParse(Controller.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.ClrName), 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(Controller.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.ClrName), Expression.Constant(start)), parameter)); } else if (options[a] == ".End") { double end; if (!double.TryParse(Controller.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.ClrName), Expression.Constant(end)), parameter)); } } break; case ComponentModel.DataAnnotations.CustomDataType.Other: if (property.CustomType == "Enum") { object result; try { result = Enum.Parse(property.ClrType, Controller.Request.QueryString["Search." + keys[i].Key]); } catch { continue; } searchItem.Enum = new EnumConverter(property.ClrType).ConvertToString(result); ParameterExpression parameter = Expression.Parameter(Metadata.Type); queryable = queryable.Where <TEntity>(Expression.Lambda <Func <TEntity, bool> >(Expression.Equal(Expression.Property(parameter, property.ClrName), Expression.Constant(result)), parameter)); } else if (property.CustomType == "Entity") { searchItem.Contains = Controller.Request.QueryString["Search." + keys[i].Key]; ParameterExpression parameter = Expression.Parameter(Metadata.Type); Expression expression = Expression.Property(Expression.Property(parameter, property.ClrName), EntityAnalyzer.GetMetadata(property.ClrType).DisplayProperty.ClrName); 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.ClrType == typeof(string)) { searchItem.Contains = Controller.Request.QueryString["Search." + keys[i].Key]; ParameterExpression parameter = Expression.Parameter(Metadata.Type); Expression expression = Expression.Property(parameter, property.ClrName); 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); } } return(searchItems.ToArray()); }
private Task Service_EntityQuery(IDomainExecutionContext context, EntityQueryEventArgs <T> e) { List <EntitySearchItem> searchItems = new List <EntitySearchItem>(); var valueProvider = context.DomainContext.GetRequiredService <IValueProvider>(); if (!valueProvider.GetValue <bool>("Search")) { return(Task.CompletedTask); } IQueryable <T> queryable = e.Queryable; var keys = valueProvider.Keys.Where(t => t.StartsWith("Search.", StringComparison.OrdinalIgnoreCase)).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; IPropertyMetadata property = Service.Metadata.SearchProperties.FirstOrDefault(t => t.ClrName.Equals(propertyName, StringComparison.OrdinalIgnoreCase)); if (property == null) { continue; } EntitySearchItem searchItem = new EntitySearchItem(); string[] options = keys[i].ToArray(); switch (property.Type) { case CustomDataType.Date: case CustomDataType.DateTime: for (int a = 0; a < options.Length; a++) { if (options[a].Equals(".Start", StringComparison.OrdinalIgnoreCase)) { DateTime start; if (!DateTime.TryParse(valueProvider.GetValue <string>("Search." + keys[i].Key + options[a]), out start)) { continue; } searchItem.MorethanDate = start; ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(Expression.Property(parameter, property.ClrName), Expression.Constant(start)), parameter)); } else if (options[a].Equals(".End", StringComparison.OrdinalIgnoreCase)) { DateTime end; if (!DateTime.TryParse(valueProvider.GetValue <string>("Search." + keys[i].Key + options[a]), out end)) { continue; } if (property.Type == CustomDataType.Date) { end = end.AddDays(1); } searchItem.LessthanDate = end; ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.LessThanOrEqual(Expression.Property(parameter, property.ClrName), Expression.Constant(end)), parameter)); } } break; case CustomDataType.Boolean: case CustomDataType.Gender: if (options[0] == "") { bool result; if (!bool.TryParse(valueProvider.GetValue <string>("Search." + keys[i].Key), out result)) { continue; } searchItem.Equal = result; ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.Equal(Expression.Property(parameter, property.ClrName), Expression.Constant(result)), parameter)); } break; case CustomDataType.Currency: case CustomDataType.Integer: case CustomDataType.Number: for (int a = 0; a < options.Length; a++) { if (options[a].Equals(".Start", StringComparison.OrdinalIgnoreCase)) { object start; try { start = TypeDescriptor.GetConverter(property.ClrType).ConvertFromString(valueProvider.GetValue <string>("Search." + keys[i].Key + options[a])); } catch { continue; } searchItem.Morethan = double.Parse(start.ToString()); ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(Expression.Property(parameter, property.ClrName), Expression.Constant(start)), parameter)); } else if (options[a].Equals(".End", StringComparison.OrdinalIgnoreCase)) { object end; try { end = TypeDescriptor.GetConverter(property.ClrType).ConvertFromString(valueProvider.GetValue <string>("Search." + keys[i].Key + options[a])); } catch { continue; } searchItem.Lessthan = double.Parse(end.ToString()); ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.LessThanOrEqual(Expression.Property(parameter, property.ClrName), Expression.Constant(end)), parameter)); } } break; case CustomDataType.Other: if (property.CustomType == "Enum") { object result; try { result = Enum.Parse(property.ClrType, valueProvider.GetValue <string>("Search." + keys[i].Key)); } catch { continue; } searchItem.Enum = new EnumConverter(property.ClrType).ConvertToString(result); ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(Expression.Equal(Expression.Property(parameter, property.ClrName), Expression.Constant(result)), parameter)); } else if (property.CustomType == "Entity") { searchItem.Contains = valueProvider.GetValue <string>("Search." + keys[i].Key); if (searchItem.Contains == null) { continue; } var isId = valueProvider.GetValue <bool?>("Search." + keys[i].Key + ".Id"); ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); if (isId.HasValue && isId.Value) { var keyProperty = EntityDescriptor.GetMetadata(property.ClrType).KeyProperty; var id = keyProperty.Converter.ConvertFrom(searchItem.Contains); Expression expression = Expression.Property(Expression.Property(parameter, property.ClrName), keyProperty.ClrName); expression = Expression.Equal(expression, Expression.Constant(id)); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(expression, parameter)); } else { Expression expression = Expression.Property(Expression.Property(parameter, property.ClrName), EntityDescriptor.GetMetadata(property.ClrType).DisplayProperty.ClrName); expression = Expression.Call(expression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(searchItem.Contains)); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(expression, parameter)); } } else if (property.ClrType == typeof(string)) { searchItem.Contains = valueProvider.GetValue <string>("Search." + keys[i].Key); if (searchItem.Contains == null) { continue; } ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); Expression expression = Expression.Property(parameter, property.ClrName); expression = Expression.Call(expression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(searchItem.Contains)); queryable = queryable.Where <T>(Expression.Lambda <Func <T, bool> >(expression, parameter)); } break; default: if (property.ClrType == typeof(string)) { searchItem.Contains = valueProvider.GetValue <string>("Search." + keys[i].Key); if (searchItem.Contains == null) { continue; } ParameterExpression parameter = Expression.Parameter(Service.Metadata.Type); Expression expression = Expression.Property(parameter, property.ClrName); expression = Expression.Call(expression, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), Expression.Constant(searchItem.Contains)); queryable = queryable.Where <T>(Expression.Lambda <Func <T, 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); } e.Queryable = queryable; } context.DomainContext.DataBag.SearchItem = searchItems.ToArray(); return(Task.CompletedTask); }
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)); }