Фильтрация в скрипте Версия 5.1.1.157

Как сделать фильтрацию или в следующим примере:

использовал

{"logicalOperation", LogicalOperationStrict.Or}
не работает

filters.Add(new Dictionarystring, object> {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "Debt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                   
                                                                }
                                                        );
                                filters.Add(new Dictionarystring, object> {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "ReceivDebt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                 
                                                                }
                                                        );

Нравится

11 комментариев

Здравствуйте, Баглан!
А работает, если применять только один фильтр?

"Андрей Каспаревич" написал:filters.Add(new Dictionary {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "Debt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                   
                                                                }
                                                        );

Если применять 1 фильтр работает
к примеру этот:
filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.IsNotNull},
{"leftExpressionColumnPath", "Debt.Id"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object[] {Guid.Empty}}

}
);

Баглан, приведите, пожалуйста, полный код скрипта.
В частности, интересует инициализация filters. Должно быть что-то вроде:

filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or);

"Андрей Каспаревич" написал:

Баглан, приведите, пожалуйста, полный код скрипта.

В частности, интересует инициализация filters. Должно быть что-то вроде:

filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or);

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки

Андрей добрый день, высылаю полный текст скрипта на C#

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
                Collection<Dictionary<string, object>> filters = e.Filters;
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.Equal}, 
	                               {"leftExpressionColumnPath", "Type.Id"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {activityTypeId}}
								}
							); 
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.LessOrEqual}, 
	                               {"leftExpressionColumnPath", "StartDate"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {UserConnection.CurrentUser.GetCurrentDateTime()}}
								}
							); 							
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.Equal}, 
	                               {"leftExpressionColumnPath", "Status.Id"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {NotStartedStatusId, InWorkStatusId}}
								}
							); 	
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.IsNotNull}, 
	                               {"leftExpressionColumnPath", "Debt.Id"},
	                               {"useDisplayValue", false},
								   {"rightExpressionParameterValues", new object[] {Guid.Empty}},
								   {"logicalOperation", LogicalOperationStrict.Or}
								}
							);
				/*
				filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.IsNotNull}, 
	                               {"leftExpressionColumnPath", "ReceivDebt.Id"},
	                               {"useDisplayValue", false},
								   {"rightExpressionParameterValues", new object[] {Guid.Empty}},
								   {"logicalOperation", LogicalOperationStrict.Or}
								}
							); */
};

Баглан, судя по коду, проблема в том, что фильтры добавляются по одному, а не блоком. То есть Вам нужно сформировать блок фильтров с логическим оператором и уже его добавлять в e.Filters.
Попробуйте так:

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
                var filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or); 
                filters.Add( structure.CreateFilterWithParameters( dataSource.Schema, 
                FilterComparisonType.Equal, "Type.Id", activityTypeId)); 
                filters.Add( structure.CreateFilterWithParameters(dataSource.Schema, 
                FilterComparisonType.LessOrEqual, "StartDate",   UserConnection.CurrentUser.GetCurrentDateTime());                                                      
               //....
                e.Filters.Add(filters);

"Андрей Каспаревич" написал:{"comparisonType", FilterComparisonType.IsNotNull},

Ругаеться на это e.Filters.Add(structure); тип не верный не верно передаем параметр structure, должно быть таким образом: Collection>

DataSource dataSource = Page.ActivityDataSource;
				var structure = dataSource.CurrentStructure;
				var filterGroupName = "CustomFilters";
				//remove existing filters
                var filters = dataSource.FindFiltersGroupByName(filterGroupName);
                if (filters != null) {
	                structure.Filters.Remove(filters);
                }
                filters = structure.CreateFiltersGroup(filterGroupName, LogicalOperationStrict.And); 
                filters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.Equal, "Type.Id", activityTypeId)); 
                filters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.LessOrEqual, "StartDate",   UserConnection.CurrentUser.GetCurrentDateTime()));   
 
				var statusFilters = new DataSourceFilterCollection() {
	                LogicalOperation = LogicalOperationStrict.Or,
                };
				statusFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.Equal, "Status.Id", NotStartedStatusId));
				statusFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.Equal, "Status.Id", InWorkStatusId));
				filters.Add(statusFilters);
 
				var debtFilters = new DataSourceFilterCollection() {
	                LogicalOperation = LogicalOperationStrict.Or,
                };
				debtFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.IsNotNull, "Debt.Id"));
				debtFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.IsNotNull, "ReceivDebt.Id"));
				filters.Add(debtFilters);
				structure.Filters.Add(filters);
				e.Filters.Add(structure);

Здравствуйте, Баглан!
Уточнил информацию у разработчиков.
Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:
1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;
2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.
Пример реализации второго варианта:

List<object> offeringList = new List<object>();
var offeringSelect = new Select(UserConnection).
                Column("o", "Id").
                From("Offering").As("o").
                InnerJoin("OfferingType").As("ot").
                On("o", "TypeId").IsEqual("ot", "Id"). 
                InnerJoin("Service").As("s").
                On("o", "ServiceId").IsEqual("s", "Id"). 
                InnerJoin("TypeOfService").As("tos").
                On("s", "TypeOfServiceId").IsEqual("tos", "Id").
                Where("ot", "IsService").IsEqual(Column.Parameter(true)).
                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              
                And().OpenBlock
                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).
                               Or("o", "ServiceId").IsNull().
                               Or().OpenBlock
                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).
                                               And().Exists(
                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").
                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").
                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).
                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))
                                               ).
                               CloseBlock().
                CloseBlock() as Select;
 
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {
                               while (dr.Read()) {
                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));
                               }
                }
}
 
if (offeringList.Count == 0) {
                offeringList.Add((object)Guid.Empty);
}
 
 
 
e.Filters.Clear();
var filter = new Dictionary<string, object> { 
                               { "comparisonType", FilterComparisonType.Equal }, 
                               { "leftExpressionColumnPath", "Id" },
                               { "useDisplayValue", false }, 
                               { "rightExpressionParameterValues", offeringList.ToArray()}};
e.Filters.Add(filter);

"Андрей Каспаревич" написал:

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}



if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}







e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки


Спасибо у меня получилось сделать.

"Бахгельдиев Баглан Абылаевич" написал:
Андрей Каспаревич пишет:

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}

if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}

e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки

Спасибо у меня получилось сделать.

Добрый день, Андрей после переноса в боевую среду, начало выдавать ошибку, скрипт ниже,
LookupFilter не может принять записей больше 1000, высылаю скрин и текст ошибки, прошу помочь исправить ошибку, заранее спасибо.

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
            List<object> callFromQueueList = new List<object>();
 
			var queryCallFromQueue = new Select(UserConnection)
			   .Column("a", "Id")
			   .From("Activity").As("a")
			   .Where("a", "TypeId").IsEqual(Column.Parameter(activityTypeId))
			   .And("a", "StartDate").IsLessOrEqual(Column.Parameter(UserConnection.CurrentUser.GetCurrentDateTime()))
			   .And("a", "StatusId").In(Column.Parameter(NotStartedStatusId), Column.Parameter(InWorkStatusId))
			   .And().OpenBlock("a", "DebtId").Not().IsNull()
			   .Or("a", "ReceivDebtId").Not().IsNull()
               .CloseBlock() as Select;
 
			using (var dbExecutor = UserConnection.EnsureDBConnection()) {
                   using (var dr = queryCallFromQueue.ExecuteReader(dbExecutor)) {
                          while (dr.Read()) {
                                 callFromQueueList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));
                          }
                   }
            }
			if (callFromQueueList.Count == 0) {
                callFromQueueList.Add((object)Guid.Empty);
            }
 
           e.Filters.Clear();
           var filter = new Dictionary<string, object> { 
                               { "comparisonType", FilterComparisonType.Equal}, 
                               { "leftExpressionColumnPath", "Id"},
                               { "useDisplayValue", false}, 
                               { "rightExpressionParameterValues", callFromQueueList.ToArray()}};
           e.Filters.Add(filter);
 
};

"Бахгельдиев Баглан Абылаевич" написал:
Бахгельдиев Баглан Абылаевич пишет:

Андрей Каспаревич пишет:

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}

if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}

e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки

Спасибо у меня получилось сделать.

Добрый день, Андрей после переноса в боевую среду, начало выдавать ошибку, скрипт ниже,

LookupFilter не может принять записей больше 1000, высылаю скрин и текст ошибки, прошу помочь исправить ошибку, заранее спасибо.

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {

            List<object> callFromQueueList = new List<object>();

           

                        var queryCallFromQueue = new Select(UserConnection)

                           .Column("a", "Id")

                           .From("Activity").As("a")

                           .Where("a", "TypeId").IsEqual(Column.Parameter(activityTypeId))

                           .And("a", "StartDate").IsLessOrEqual(Column.Parameter(UserConnection.CurrentUser.GetCurrentDateTime()))

                           .And("a", "StatusId").In(Column.Parameter(NotStartedStatusId), Column.Parameter(InWorkStatusId))

                           .And().OpenBlock("a", "DebtId").Not().IsNull()

                           .Or("a", "ReceivDebtId").Not().IsNull()

               .CloseBlock() as Select;

                           

                        using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                   using (var dr = queryCallFromQueue.ExecuteReader(dbExecutor)) {

                          while (dr.Read()) {

                                 callFromQueueList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                          }

                   }

            }

                        if (callFromQueueList.Count == 0) {

                callFromQueueList.Add((object)Guid.Empty);

            }



           e.Filters.Clear();

           var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal},

                               { "leftExpressionColumnPath", "Id"},

                               { "useDisplayValue", false},

                               { "rightExpressionParameterValues", callFromQueueList.ToArray()}};

           e.Filters.Add(filter);



};

Здравтсвуйте, Баглан!
Как видно из текста ошибки, это ограничение Oracle. Его можно обойти, использовав логическую операцию "OR" для объединения каждых 999 идентификаторов в списке.
(http://stackoverflow.com/questions/17842453/is-there-a-workaround-for-o…)
Таким образом, Вы можете создать двухуровневый список, каждый список из которого будет включать 999 идентификаторов и затем добавить каждый список в отдельный фильтр. Чтобы установить логическую операцию объединения фильтров, используйте код:

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);
Показать все комментарии