/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { if (context.Value is int) context.Context.PageSize = (int) context.Value; return null; }
public override string BuildPredicate(FilterOptionAttributeContext context) { if (context.Value is DateTimeRange) { var state = context.Value as DateTimeRange; if (!state.StartDate.HasValue && !state.FinishDate.HasValue) { return(null); } if (!state.FinishDate.HasValue) { return(String.Format("(T0.{0} >= '{1}')", FieldName, state.StartDate.Value.ToString(DateTimeFormat))); } if (!state.StartDate.HasValue) { return(String.Format("(T0.{0} <= '{1}')", FieldName, state.FinishDate.Value.ToString(DateTimeFormat))); } return(String.Format("(T0.{0} between '{1}' and '{2}')", FieldName, state.StartDate.Value.ToString(DateTimeFormat), state.FinishDate.Value.ToString(DateTimeFormat))); } if (context.Value is DateTime && (DateTime)context.Value != default(DateTime)) { var state = (DateTime)context.Value; return(String.Format("(T0.{0} = '{1}')", FieldName, state.ToString(DateTimeFormat))); } return(null); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { var state = new State(); context.State = state; state.AdjustedValue = context.Value as bool?; return(null); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { if (context.Value is int) { context.Context.RowStartIndex = (int)context.Value; } return(null); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации - строка поиска. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { var state = new State(); context.State = state; if (context.Value != null && context.Value is IEnumerable) { var defValue = default(int); var list = new List <int>(); var values = context.Value as IEnumerable; foreach (var value in values) { if (value is IComparable && !value.Equals(defValue)) { list.Add(Convert.ToInt32(value)); } } state.AdjustedValue = list.ToArray(); } if (state.AdjustedValue == null || state.AdjustedValue.Length == 0) { return(null); } var ids = state.AdjustedValue; if (ids.Length > 1) { context.Context.Declarations.Add(@" -- Таблица с индексами LR для ограничения поиска DECLARE @ГраницыLRДляОграниченияПоиска TABLE(L int, R int) " .FormatWith(FieldName)); StringBuilder sql = new StringBuilder(); sql.AppendFormat(@" ;INSERT @ГраницыLRДляОграниченияПоиска SELECT L, R FROM $(TableName) WHERE $(KeyField) IN ({0}) " , String.Join(",", ids.Select(num => num.ToString()).ToArray())); return(sql.ToString()); } else { context.Context.Declarations.Add(@" -- Индексы LR: {0} DECLARE @Родительский_L int, @Родительский_R int " .FormatWith(FieldName)); return(@" SELECT @Родительский_L = L, @Родительский_R = R FROM $(TableName) WHERE $(KeyField) = {0} " .FormatWith(ids[0])); } }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации - строка поиска. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { var alias = FieldNameAlias ?? FieldName; var state = new State(); context.State = state; state.AdjustedValue = ((context.Value == null) ? String.Empty : context.Value.ToString()).SplitWords(); if (String.IsNullOrEmpty(state.AdjustedValue)) { return(null); } string howSearchExpression = context.Context.HowSearchDefined ? "CASE WHEN @ГдеИскать = 1 THEN ' ' ELSE '' END +" : String.Empty; var list = state.Words = state.AdjustedValue.Split(' '); if (list.Length > 1) { //DECLARE @ИспользоватьRL_{0} bit SET @ИспользоватьRL_{0} = {1} //DECLARE @I_{0} int, @S_{0} varchar(200), @W_{0} varchar(200), @WRL_{0} varchar(200) //DECLARE @СтрокаПоиска_{0} varchar(4000) context.Context.Declarations.Add(@" -- Таблица со словами для поиска в поле: {0} DECLARE @СписокСловДляПоискаПоПолю_{0} TABLE(Слово varchar(200)) " .FormatWith(alias, UseConvertionToRL ? 1 : 0)); StringBuilder sql = new StringBuilder(); list.All(word => { sql.AppendFormat(@" ;INSERT @СписокСловДляПоискаПоПолю_{0} VALUES({3} {1}(Инвентаризация.dbo.fn_ReplaceKeySymbols('{2}'))) " , alias, UseConvertionToRL ? "Инвентаризация.dbo.fn_ReplaceRusLat" : String.Empty, word.Replace("'", "''"), howSearchExpression); return(true); }); return(sql.ToString()); } else { context.Context.Declarations.Add(@" -- Слово для поиска в поле: {0} DECLARE @СловоДляПоискаПоПолю_{0} varchar(200) " .FormatWith(alias)); return(@" SET @СловоДляПоискаПоПолю_{0} = '%'+{3} {1}(Инвентаризация.dbo.fn_ReplaceKeySymbols('{2}'))+'%' " .FormatWith(alias, UseConvertionToRL ? "Инвентаризация.dbo.fn_ReplaceRusLat" : String.Empty, state.Words[0].Replace("'", "''"), howSearchExpression)); } }
/// <summary> /// Строит предикат - SQL-код условия фильтрации в конструкции WHERE. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код условия фильтрации в конструкции WHERE /// </returns> public override string BuildPredicate(FilterOptionAttributeContext context) { var state = context.State as State; if (state == null || state.AdjustedValue == null || state.AdjustedValue.Length == 0) { return(null); } if (state.AdjustedValue.Length > 1) { return(@"EXISTS(SELECT COUNT(*) FROM @ГраницыLRДляОграниченияПоиска WHERE $(TableAlias).L >= L AND $(TableAlias).R <= R)"); } return(@"($(TableAlias).L >= @Родительский_L AND $(TableAlias).R <= @Родительский_R)"); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { /*if (!context.Context.HowSearchDefined) { * context.Context.Declarations.Add(@" * DECLARE @ГдеИскать INT SET @ГдеИскать = 0 * "); * context.Context.HowSearchDefined = true; * } * * if (context.Value is int) { * return @" * SET @ГдеИскать = {0} * ".FormatWith(context.Value); * }*/ return(null); }
/// <summary> /// Строит предикат - SQL-код условия фильтрации в конструкции WHERE. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код условия фильтрации в конструкции WHERE /// </returns> public override string BuildPredicate(FilterOptionAttributeContext context) { var alias = FieldNameAlias ?? FieldName; var state = context.State as State; if (state == null || state.AdjustedValue == null || state.AdjustedValue.Length == 0) { return(null); } string fieldExpression = String.Empty; string concatExpression = String.Empty; if (!String.IsNullOrEmpty(ConcatinationExpression)) { concatExpression = ConcatinationExpression; } if (!String.IsNullOrEmpty(FieldName)) { fieldExpression = "T0.{0}".FormatWith(FieldName); if (concatExpression.Length > 0) { concatExpression = concatExpression.Insert(0, " + "); } } fieldExpression = "{0}{1}".FormatWith(fieldExpression, concatExpression); if (UseConvertionToRL && !FieldValueInRL) { fieldExpression = "Инвентаризация.dbo.fn_ReplaceRusLat({0})".FormatWith(fieldExpression); } if (state.Words.Length > 1) { return(@"((SELECT COUNT(*) FROM @СписокСловДляПоискаПоПолю_{0} WHERE ' '+{1} LIKE '%'+Слово+'%') = {2})" .FormatWith(alias, fieldExpression, state.Words.Length)); } return(@"(' '+{1} LIKE @СловоДляПоискаПоПолю_{0})" .FormatWith(alias, fieldExpression)); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { var state = new State(); context.State = state; if (context.Value != null && context.Value is IEnumerable) { var defValue = this.ValueType.IsValueType ? Activator.CreateInstance(ValueType) : null; var list = new List <IComparable>(); var values = context.Value as IEnumerable; foreach (var value in values) { if (value is IComparable && defValue != value) { list.Add((IComparable)(QuoteValues ? GetQuotedValue(value) : value)); } } state.AdjustedValue = list.ToArray(); } return(null); }
/// <summary> /// Строит предикат - SQL-код условия фильтрации в конструкции WHERE. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код условия фильтрации в конструкции WHERE /// </returns> public override string BuildPredicate(FilterOptionAttributeContext context) { var state = context.State as State; if (state == null || state.AdjustedValue == null || !state.AdjustedValue.HasValue) { return(null); } if (!String.IsNullOrWhiteSpace(CustomTrueExpression) && state.AdjustedValue.Value) { return(String.Format(CustomTrueExpression, FieldName)); } if (!String.IsNullOrWhiteSpace(CustomFalseExpression) && !state.AdjustedValue.Value) { return(String.Format(CustomFalseExpression, FieldName)); } string expression = String.Format(" = {0}", state.AdjustedValue.Value ? 1 : 0); return(String.Format("(T0.{0} {1})", FieldName, expression)); }
/// <summary> /// Строит предикат - SQL-код условия фильтрации в конструкции WHERE. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код условия фильтрации в конструкции WHERE /// </returns> public override string BuildPredicate(FilterOptionAttributeContext context) { var state = context.State as State; if (state == null || state.AdjustedValue == null) { return(null); } int count = state.AdjustedValue.Count(); if (!AllowEmpty && count == 0) { return(null); } string expression = String.Empty; if (count == 0) { return(String.Format( "(T0.{0} IS {1}NULL)", FieldName, Condition == ValueCondition.Exclude ? "NOT " : "" )); } if (count == 1) { expression = String.Format("{1}= {0}", state.AdjustedValue.First(), Condition == ValueCondition.Exclude?"!":""); } else { expression = String.Format("{1}IN ({0})", String.Join(", ", state.AdjustedValue), Condition == ValueCondition.Exclude ? "NOT " : ""); } return(String.Format("(T0.{0} {1})", FieldName, expression)); }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public override string BuildPrecode(FilterOptionAttributeContext context) { context.Context.OrderBy = context.Value as List <string>; return(null); }
/// <summary> /// Builds the internal. /// </summary> /// <param name="commandContext">The command context.</param> protected virtual void BuildInternal(CommandContext commandContext) { var properties = ParametersType .GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ) .Where(prop => prop.IsDefined(typeof(FilterOptionAttribute), false)); string output = null; var howSearchProp = properties.FirstOrDefault(pr => pr is HowSearchFilterOptionAttribute); var pro = properties.FirstOrDefault(pr => pr is SearchStringFilterOptionAttribute); if (pro != null) { var context = new FilterOptionAttributeContext { Context = commandContext, Property = pro, Value = pro.GetValue(commandContext.Parameters, null) }; if (!string.IsNullOrEmpty((string)context.Value)) { if (!commandContext.HowSearchDefined && howSearchProp != null) { commandContext.Declarations.Add(@" DECLARE @ГдеИскать INT SET @ГдеИскать = {0} " .FormatWith(context.Value is int?context.Value.ToString() : "0")); commandContext.HowSearchDefined = true; } } } foreach (var property in properties) { var option = property.GetCustomAttributes(typeof(FilterOptionAttribute), false).FirstOrDefault() as FilterOptionAttribute; var context = new FilterOptionAttributeContext { Context = commandContext, Property = property, Value = property.GetValue(commandContext.Parameters, null) }; output = option.BuildPrecode(context); if (!String.IsNullOrEmpty(output)) { commandContext.Sql.AppendLine(sqlPreprocessor(this, output)); } output = option.BuildPredicate(context); if (!String.IsNullOrEmpty(output)) { commandContext.Predicates.Add(sqlPreprocessor(this, output)); } } if (commandContext.RowStartIndex > 0) { commandContext.Declarations.Add(@" ;-- Определим таблицу для результатов поиска DECLARE @РезультатПоиска TABLE(Код INT, Порядок BIGINT IDENTITY(0,1)) " ); } if (commandContext.Declarations.Count > 0) { commandContext.Sql.Insert(0, String.Join(";", commandContext.Declarations)); } int top = 0; if (commandContext.PageSize > 0) { top += commandContext.PageSize; if (commandContext.RowStartIndex > 0) { top += commandContext.RowStartIndex; } } if (commandContext.RowStartIndex > 0) { commandContext.Sql.AppendFormat(@" INSERT INTO @РезультатПоиска(Код) " , this.UniqueIdField, commandContext.RowStartIndex, commandContext.PageSize); } commandContext.Sql.AppendFormat(@" SELECT {2} {1} FROM {0} T0 {3} " , TableOrViewName, (commandContext.RowStartIndex > 0) ? UniqueIdField : (String.IsNullOrEmpty(FieldList) ? " * " : FieldList), (top > 0) ? " TOP {0} ".FormatWith(top) : String.Empty, Joins ?? String.Empty ); commandContext.Sql.AppendFormatIfTrue(commandContext.Predicates.Count > 0, @"WHERE {0} " , String.Join(@" AND " , commandContext.Predicates)); commandContext.Sql.AppendFormatIfTrue(commandContext.OrderBy != null && commandContext.OrderBy.Count > 0, @"ORDER BY {0} " , String.Join(@" , " , commandContext.OrderBy)); if (commandContext.RowStartIndex > 0) { commandContext.Sql.AppendFormat(@" ;-- Вернём результат SELECT {1} FROM @РезультатПоиска РП INNER JOIN {0} T0 ON РП.Код = T0.{2} WHERE РП.Порядок >= {3}{4} ORDER BY РП.Порядок " , TableOrViewName , String.IsNullOrEmpty(FieldList) ? " * " : FieldList , UniqueIdField , commandContext.RowStartIndex , (commandContext.PageSize > 0) ? @" AND РП.Порядок < {0} ".FormatWith(top) : String.Empty); } }
/// <summary> /// Строит подготовительный SQL-код для критерия фильтрации. /// </summary> /// <param name="context">контекст для атрибута критерия фильтрации.</param> /// <returns> /// SQL-код для критерия фильтрации, который должен быть выполнен перед основным запросом /// </returns> public virtual string BuildPrecode(FilterOptionAttributeContext context) { return(null); }