/// <summary>
    ///
    /// </summary>
    /// <param name="option"></param>
    /// <returns></returns>
    public static DynamicFilterInfo ToDynamicFilter(this QueryPageOptions option)
    {
        var ret = new DynamicFilterInfo()
        {
            Filters = new List <DynamicFilterInfo>()
        };

        foreach (var filter in option.Filters.Concat(option.Searchs))
        {
            var item = new DynamicFilterInfo()
            {
                Filters = new List <DynamicFilterInfo>()
            };
            var actions = filter.GetFilterConditions();
            foreach (var f in actions)
            {
                item.Logic = f.FilterLogic.ToDynamicFilterLogic();
                item.Filters.Add(new DynamicFilterInfo()
                {
                    Field    = f.FieldKey,
                    Value    = f.FieldValue,
                    Operator = f.FilterAction.ToDynamicFilterOperator()
                });
            }
            ret.Filters.Add(item);
        }
        return(ret);
    }
예제 #2
0
        public async Task <DynamicFilterInfo> GetPermissionDynamicFilterAsync(string permissionId, string moduleKey)
        {
            var conditions = await GetPermissionConditionsAsync(permissionId);

            var currentConditions = conditions.Where(x => x.Code == moduleKey);

            var cons = new List <DynamicFilterInfo>();

            foreach (var item in currentConditions)
            {
                var conditionStr = item.Condition?
                                   .Replace("{UserId}", _authUser.Id)
                                   .Replace("{UserName}", _authUser.UserName)
                                   .Replace("{UserGroupId}", _authUser.GroupId)
                                   .Replace("{UserPermissionId}", _authUser.PermissionId);

                var dyCons = Newtonsoft.Json.JsonConvert.DeserializeObject <List <DynamicFilterInfo> >(conditionStr);
                foreach (var it in dyCons)
                {
                    cons.Add(it);
                }
            }

            var condition = new DynamicFilterInfo();

            condition.Logic   = DynamicFilterLogic.Or;
            condition.Filters = cons;
            return(condition);
        }
예제 #3
0
        public async Task <IActionResult> DynamicQueryAsync([FromQuery] DynamicFilterInfo dynamicFilter)
        {
            var result = await _dataBaseOptionService.DynamicQueryAsync(dynamicFilter);

            return(Ok(new ResponseResult {
                Result = result
            }));
        }
예제 #4
0
        public static ISelect <T1> Where <T1>(this ISelect <T1> select, string field, DynamicFilterOperator filterOperator, object value)
        {
            var filter = new DynamicFilterInfo {
                Field = field, Operator = filterOperator, Value = value
            };
            Expression <Func <T1, bool> > exp = GetWhereExpression(select, filter);

            return(select.Where(exp));
        }
예제 #5
0
        public void DynamicLinqTest()
        {
            using (var freeSql = new FreeSqlBuilder()
                                 .UseConnectionString(DataType.Sqlite, "Data Source=:memory:;")
                                 .UseAutoSyncStructure(true)
                                 .Build())
            {
                freeSql.Aop.CurdBefore += (s, e) =>
                {
                    Trace.WriteLine(e.Sql);
                };

                freeSql.Insert(
                    Enumerable.Range(1, 100)
                    .Select(i => new Topic {
                    Title = $"new topic {i}", Clicks = 100
                })
                    .ToList())
                .ExecuteAffrows();

                // 常规用法
                var list1 = freeSql.Select <Topic>()
                            .Where(t => t.Title.StartsWith("new topic 1"))
                            .ToList();

                // 借助 DynamicExpressionParser
                var list2 = freeSql.Select <Topic>()
                            .WhereDynamicLinq("Title.StartsWith(\"new topic 1\")")
                            .ToList();

                // 拓展 DynamicFilter
                var dynmaicFilterInfo = new DynamicFilterInfo
                {
                    Field    = $"{nameof(DynamicLinqCustom.DynamicLinq)} {typeof(DynamicLinqCustom).FullName},{typeof(DynamicLinqCustom).Assembly.FullName}",
                    Operator = DynamicFilterOperator.Custom,
                    Value    = "Title.StartsWith(\"new topic 1\")",
                };
                var list3 = freeSql.Select <Topic>()
                            .WhereDynamicFilter(dynmaicFilterInfo)
                            .ToList();
            }
        }
예제 #6
0
        /// <summary>
        /// 生成Where子句的DynamicFilterInfo对象
        /// </summary>
        /// <param name="option"></param>
        /// <param name="isSerach"></param>
        /// <returns></returns>
        private DynamicFilterInfo?MakeDynamicFilterInfo(QueryPageOptions option, out bool isSerach)
        {
            var filters = new List <DynamicFilterInfo>();

            object?searchModel = option.SearchModel;
            Type   type        = searchModel.GetType();

            var instance = Activator.CreateInstance(type);

            if (string.IsNullOrEmpty(option.SearchText))
            {
                //生成高级搜索子句
                //TODO : 支持更多类型
                foreach (var propertyinfo in type.GetProperties().Where(a => a.PropertyType == typeof(string) || a.PropertyType == typeof(int)).ToList())
                {
                    if (propertyinfo.GetValue(searchModel) != null && !propertyinfo.GetValue(searchModel).Equals(propertyinfo.GetValue(instance)))
                    {
                        string propertyValue = propertyinfo.GetValue(searchModel).ToString();
                        if (propertyinfo.PropertyType == typeof(int) && !IsNumeric(propertyValue))
                        {
                            continue;
                        }

                        filters.Add(new DynamicFilterInfo()
                        {
                            Field    = propertyinfo.Name,
                            Operator = propertyinfo.PropertyType == typeof(int) ? DynamicFilterOperator.Equal : DynamicFilterOperator.Contains,
                            Value    = propertyinfo.PropertyType == typeof(int) ? Convert.ToInt32(propertyValue) : propertyValue,
                        });
                    }
                }
            }
            else
            {
                //生成默认搜索子句
                //TODO : 支持更多类型
                foreach (var propertyinfo in type.GetProperties().Where(a => a.PropertyType == typeof(string) || a.PropertyType == typeof(int)).ToList())
                {
                    if (propertyinfo.PropertyType == typeof(int) && !IsNumeric(option.SearchText))
                    {
                        continue;
                    }

                    filters.Add(new DynamicFilterInfo()
                    {
                        Field    = propertyinfo.Name,
                        Operator = propertyinfo.PropertyType == typeof(int) ? DynamicFilterOperator.Equal : DynamicFilterOperator.Contains,
                        Value    = propertyinfo.PropertyType == typeof(int) ? Convert.ToInt32(option.SearchText) : option.SearchText,
                    });
                }
            }

            if (option.Filters.Any())
            {
                foreach (var item in option.Filters)
                {
                    var filter         = item.GetFilterConditions().First();
                    var filterOperator = DynamicFilterOperator.Contains;

                    switch (filter.FilterAction)
                    {
                    case FilterAction.Contains:
                        filterOperator = DynamicFilterOperator.Contains;
                        break;

                    case FilterAction.NotContains:
                        filterOperator = DynamicFilterOperator.NotContains;
                        break;

                    case FilterAction.NotEqual:
                        filterOperator = DynamicFilterOperator.NotEqual;
                        break;

                    case FilterAction.Equal:
                        filterOperator = DynamicFilterOperator.Equal;
                        break;
                    }

                    filters.Add(new DynamicFilterInfo()
                    {
                        Field    = filter.FieldKey,
                        Operator = filterOperator,
                        Value    = filter.FieldValue,
                    });
                }
            }

            if (filters.Any())
            {
                DynamicFilterInfo dyfilter = new DynamicFilterInfo()
                {
                    Logic   = string.IsNullOrEmpty(option.SearchText) ? DynamicFilterLogic.And : DynamicFilterLogic.Or,
                    Filters = filters
                };
                isSerach = true;
                return(dyfilter);
            }

            isSerach = false;
            return(null);
        }
예제 #7
0
        private static Expression GetWhereExpression <T1>(ISelect <T1> select, TableRefTree deepest, DynamicFilterInfo filterInfo, string[] properties, Expression body, ref int manyLevel)
        {
            while (deepest.Parent != null && deepest.TableRef.RefType != TableRefType.ManyToMany && deepest.TableRef.RefType != TableRefType.OneToMany)
            {
                deepest = deepest.Parent;
            }
            manyLevel++;
            if (manyLevel == 1)
            {
                filterInfo = new DynamicFilterInfo
                {
                    Field    = string.Join(".", properties.Skip(deepest.Level - 1)),
                    Operator = filterInfo.Operator,
                    Value    = filterInfo.Value,
                };
                deepest = deepest.Parent;
                return(GetWhereExpression(select, deepest, filterInfo, properties, body, ref manyLevel));
            }
            if (body == null)
            {
                body = Expression.Parameter(deepest.TableInfo.Type, $"t{deepest.Level}");
                var sub = deepest;
                do
                {
                    sub  = sub.Subs.First();
                    body = Expression.Property(body, sub.TableRef.Property);
                } while (sub.TableRef.RefType != TableRefType.ManyToMany && sub.TableRef.RefType != TableRefType.OneToMany);

                var selectMethod = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.Name == "AsSelect" && a.ContainsGenericParameters && a.GetParameters().Count() == 1).MakeGenericMethod(sub.TableRef.RefEntityType);
                body = Expression.Call(null, selectMethod, body);
                var asMethod        = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType).GetMethod("As");
                var constExpression = Expression.Constant($"t{deepest.Level}");
                body = Expression.Call(body, asMethod, constExpression);
                var whereDynamicFilterMethod = typeof(ISelect0 <,>).MakeGenericType(typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType), sub.TableRef.RefEntityType).GetMethod("WhereDynamicFilter");
                body = Expression.Call(body, whereDynamicFilterMethod, Expression.Constant(filterInfo));
                var anyMethod = typeof(ISelect0 <,>).MakeGenericType(typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType), sub.TableRef.RefEntityType).GetMethod("Any");
                body = Expression.Call(body, anyMethod);

                deepest = deepest.Parent;
            }
            else
            {
                Expression subBody = Expression.Parameter(deepest.TableInfo.Type, $"t{deepest.Level}");
                var        sub     = deepest;
                do
                {
                    sub     = sub.Subs.First();
                    subBody = Expression.Property(subBody, sub.TableRef.Property);
                } while (sub.TableRef.RefType != TableRefType.ManyToMany && sub.TableRef.RefType != TableRefType.OneToMany);

                var selectMethod = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.Name == "AsSelect" && a.ContainsGenericParameters && a.GetParameters().Count() == 1).MakeGenericMethod(sub.TableRef.RefEntityType);
                subBody = Expression.Call(null, selectMethod, subBody);
                var anyMethod = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType).GetMethod("Any");

                var funcType      = typeof(Func <,>).MakeGenericType(sub.TableRef.RefEntityType, typeof(bool));
                var parameterBody = Expression.Parameter(sub.TableInfo.Type, $"t{sub.Level}");
                var lambda        = Expression.Lambda(funcType, body, parameterBody);
                body = Expression.Call(subBody, anyMethod, lambda);

                deepest = deepest.Parent;
            }

            if (deepest == null)
            {
                var funcType      = typeof(Func <,>).MakeGenericType(typeof(T1), typeof(bool));
                var parameterBody = Expression.Parameter(typeof(T1), "t1");
                return(Expression.Lambda(funcType, body, parameterBody));
            }
            else
            {
                return(GetWhereExpression(select, deepest, filterInfo, properties, body, ref manyLevel));
            }
        }
예제 #8
0
        public static Expression <Func <T1, bool> > GetWhereExpression <T1>(ISelect <T1> select, DynamicFilterInfo filter)
        {
            var properties = filter.Field.Split('.');
            var tree       = TableRefTree.GetTableRefTree(select, properties.Length, properties);

            // 检索
            var treeList        = GetTreeList(tree).ToList();
            var deepest         = treeList.Last();
            var collectionNodes = treeList.Where(a => a.TableRef.RefType == TableRefType.OneToMany || a.TableRef.RefType == TableRefType.ManyToMany).ToList();

            if (deepest.Level != properties.Length)
            {
                throw new Exception($"当前类型{typeof(T1)}导航属性{filter.Field}匹配检索失败");
            }
            if (collectionNodes.Count == 0)
            {
                throw new Exception($"当前类型{typeof(T1)}导航属性{filter.Field}不包含{TableRefType.OneToMany}或者{nameof(TableRefType.ManyToMany)}关系");
            }

            var selectMethod        = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.ContainsGenericParameters && a.GetParameters().Count() == 1);
            var parameterExpression = Expression.Parameter(typeof(T1), "t");
            var manyLevel           = 0;
            var exp = GetWhereExpression(select, deepest, filter, properties, null, ref manyLevel);

            return(exp as Expression <Func <T1, bool> >);
        }
예제 #9
0
        public void WhereByPropertyTest()
        {
            using (var freeSql = new FreeSqlBuilder()
                                 .UseConnectionString(DataType.Sqlite, "Data Source=:memory:;")
                                 .UseAutoSyncStructure(true)
                                 .Build())
            {
                freeSql.Aop.CurdBefore += (s, e) =>
                {
                    Trace.WriteLine(e.Sql);
                };

                var company = new Company {
                    Id = Guid.NewGuid(), Code = "CO001"
                };
                var department = new Department {
                    Id = Guid.NewGuid(), Code = "D001", CompanyId = company.Id
                };
                var orgnization = new Orgnization {
                    Code = "C001", CompanyId = company.Id
                };
                freeSql.Insert(company).ExecuteAffrows();
                freeSql.Insert(orgnization).ExecuteAffrows();
                freeSql.Insert(department).ExecuteAffrows();

                var materials = new[]
                {
                    new Material {
                        Code = "TEST1", Units = new List <Unit> {
                            new Unit {
                                Code = "KG"
                            }
                        }
                    },
                    new Material {
                        Code = "TEST2", Units = new List <Unit> {
                            new Unit {
                                Code = "KG"
                            }
                        }
                    }
                };

                var repo1 = freeSql.GetGuidRepository <Material>();
                repo1.DbContextOptions.EnableCascadeSave = true;
                repo1.Insert(materials);


                var order = new Order
                {
                    Code          = "X001",
                    OrgnizationId = orgnization.Id,
                    OrderItems    = new List <OrderItem>
                    {
                        new OrderItem {
                            ItemCode = "01", MaterialId = materials[0].Id
                        },
                        new OrderItem {
                            ItemCode = "02", MaterialId = materials[1].Id
                        },
                    }
                };

                var repo2 = freeSql.GetGuidRepository <Order>();
                repo2.DbContextOptions.EnableCascadeSave = true;
                repo2.Insert(order);

                // 根据导航属性过滤数据
                //var list1 = freeSql.Select<Order>().Where(t => t.OrderItems.Any(t1 => t1.Material.Units.Any(t2 => t2.Code == "KG"))).ToList();
                var filterInfo1 = new DynamicFilterInfo
                {
                    Field    = "Code",
                    Operator = DynamicFilterOperator.Eq,
                    Value    = "KG",
                };
                var list1 = freeSql.Select <Order>().Where(t => t.OrderItems.Any(t1 => t1.Material.Units.AsSelect().WhereDynamicFilter(filterInfo1).Any())).ToList();

                // 导航属性如果是 OneToOne 或者 ManyToOne 默认支持
                var filterInfo2 = new DynamicFilterInfo
                {
                    Field    = "Orgnization.Company.Code",
                    Operator = DynamicFilterOperator.Eq,
                    Value    = "CO001",
                };
                //var list2 = freeSql.Select<Order>().Where(t => t.Orgnization.Company.Code == "CO001").ToList();
                var list2 = freeSql.Select <Order>().WhereDynamicFilter(filterInfo2).ToList();

                // 实现效果 OrderItems.Material.Units.Code == "KG"
                var list3 = freeSql.Select <Order>().Where("OrderItems.Material.Units.Code", DynamicFilterOperator.Eq, "KG").ToList();

                // 实现效果 OrderItems.Material.Code == "TEST1"
                // Error SQL:
                // SELECT a."Id", a."Code", a."OrgnizationId"
                // FROM "Order" a
                // WHERE (exists(SELECT 1
                //     FROM "OrderItem" a
                //     LEFT JOIN "Material" a__Material ON a__Material."Id" = a."MaterialId"
                //     WHERE (a__Material."Code" = 'TEST1') AND (a."OrderId" = a."Id")
                //     limit 0,1))
                var list4 = freeSql.Select <Order>().Where("OrderItems.Material.Code", DynamicFilterOperator.Eq, "TEST1").ToList();


                // 拓展 DynamicFilter
                var dynmaicFilterInfo = new DynamicFilterInfo
                {
                    Field    = $"{nameof(DynamicLinqCustom.WhereNavigation)} {typeof(DynamicLinqCustom).FullName},{typeof(DynamicLinqCustom).Assembly.FullName}",
                    Operator = DynamicFilterOperator.Custom,
                    Value    = JsonConvert.SerializeObject(new DynamicFilterInfo {
                        Field = "OrderItems.Material.Units.Code", Operator = DynamicFilterOperator.Eq, Value = "KG"
                    }),
                };
                var list5 = freeSql.Select <Order>()
                            .WhereDynamicFilter(dynmaicFilterInfo)
                            .ToList();
            }
        }
예제 #10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="dynamicFilter"></param>
 /// <returns></returns>
 public async Task <ResponseResult <IList <XXXAo> > > DynamicQueryAsync(DynamicFilterInfo dynamicFilter)
 {
     return(await Task.FromResult(new ResponseResult <IList <XXXAo> > {
     }));
 }
예제 #11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="dynamicFilter"></param>
 /// <returns></returns>
 public async Task <ResponseResult <IList <XXXAo> > > DynamicQueryAsync(DynamicFilterInfo dynamicFilter)
 {
     throw new System.NotImplementedException();
 }