select
запрос
Коллекция
Технические вопросы
5.x

Передать в условие запроса свою коллекцию значений

Добрый день, коллеги!

Имеется примерно такой запрос:

var newSelect = new Select(CurrentUserConnection)
        .Column("Table1", "Column1").As("Column1")
        .From("Table1").As("Table1")
        .Where("Table1", "Column2").IsNotEqual(  ...  ) as Select;

И имеется некоторая коллекция значений, к примеру:

List myList = new List();

Вопрос в следующем: Каким образом можно в условие запроса передать список значений моей коллекции (будь то Array, ArrayList, List, Dictionary, Hashtable, SortedList или другое - значения не имеет)?

Условно говоря, мне нужно мою коллекцию представить в виде типа "Select", чтобы можно было использовать в месте отмеченном 3-мя точками, - это если следовать сигнатуре этих методов, согласно описанию из SDK (www.terrasoft.ru/bpmonlinesdk/). Но как это сделать? Прошу помощи!

Нравится

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

Виталий, для этого нужно использовать конструкцию .Not().In(массив_или_список_идентификаторов) .
Пример использования (схема EditSynchUserInSynchRole):
[csharp]
var ldapGroupsIds = new List();
var ldapUserLoginAttribute = SysSettings.GetValue(UserConnection, "LDAPUserLoginAttribute").ToString();
using (var ldapUtils = new LdapUtilities(UserConnection)) {
var usersCollection = ldapUtils.GetUsersAttributesByFilter(ldapUserLoginAttribute + "=" + ldapEntry, new [] {"distinguishedName"});
var userDn = string.Empty;
foreach (SearchResultEntry user in usersCollection) {
userDn = user.DistinguishedName;
break;
}
var ldapGroupIdentityAttribute = SysSettings.GetValue(UserConnection, "LDAPGroupIdentityAttribute").ToString();
var groupsCollection = ldapUtils.GetGroupsAttributesByFilter("member=" + userDn, new [] {ldapGroupIdentityAttribute});
foreach(SearchResultEntry group in groupsCollection) {
ldapGroupsIds.Add(new QueryParameter(ldapUtils.IdentityAttributeToString(group.Attributes[ldapGroupIdentityAttribute][0])));
}
}

if (ldapGroupsIds.Count < 1) {
return true;
}

var delete = new Delete(UserConnection).From("SysUserInRole").
Where("SysUserId").IsEqual(Column.Parameter(userId)).
And().Exists(new Select(UserConnection).
Column("Id").From("SysAdminUnit").
Where("SysUserInRole", "SysRoleId").IsEqual("SysAdminUnit", "Id").
And("SynchronizeWithLDAP").IsEqual(Column.Parameter(true)).
And("LDAPEntryId").Not().In(ldapGroupsIds));
delete.Execute();
[/csharp]
Если же передавать массив, то так (схема AdministrativeGrantedRightsGridPage):
[csharp]
object[] objectParameters = new object[adminUnitCollection.Count];
for (int i = 0; i < adminUnitCollection.Count; i++) {
objectParameters[i] = adminUnitCollection[i];
}
}
var entitySchemaManager = Page.UserConnection.EntitySchemaManager;
var rightsSchema = entitySchemaManager.GetInstanceByName("SysAdminUnitGrantedRight");
var select = new Select(Page.UserConnection)
.Column(rightsSchema.Name, "Id")
.Column(rightsSchema.Name, "GrantorSysAdminUnitId")
.Column("Grantor", "Name").As("GrantorSysAdminUnitName")
.From(rightsSchema.Name)
.InnerJoin("SysAdminUnit").As("Grantor").On("Grantor", "Id").IsEqual(rightsSchema.Name, "GrantorSysAdminUnitId")
.Where(rightsSchema.Name, "GranteeSysAdminUnitId").In(Column.Parameters(objectParameters))
.OrderByAsc("Grantor", "Name") as Select;
[/csharp]

Хм... Честно говоря, если судить по информации из SDK (http://i.piccy.info/i9/fa961117bdc660b65920ae24393d4c3e/1452507140/1535…), то оператор "In()" не принимает произвольную коллекцию, потому и решил переспросить. Во всяком случае, вопрос закрыт. В очередной раз спасибо Вам, Александр!

Я тоже думал, что только массивы из Object, но оказалось, что не только массивы.
В первом примере обратите внимание, что коллекция из элементов именно типа QueryParameter.

А это действительно важно, использовать именно тип "QueryParameter"? Т.е., к примеру:

[code]
List guids = new List();
[/code]

нельзя использовать? Или тот же тип "string"? В том же SDK есть только такой пример: http://i.piccy.info/i9/7c65675471d92405256ab8d1e300693f/1452512386/1789…

Если следовать этому описанию, то коллекция ГУИДов должна выглядеть так:

[code]
List guids = new List();
guids.Add(new QueryParameter((new Guid("...")).ToString()))
[/code]

Верно ли это? Тогда я не смогу указать оператор "In()" для колонки, содержащую тип "Guid", т.к. я буду проверять наличие текущей записи в коллекции guids, а у нее QueryParameter содержит тип "string". Что-то тут нечисто... Подскажете, как быть?:confused:

Попробуйте сделать как в моём первом примере, там как раз сравнивается со списком из Guid, хоть и приводится к строке.

Показать все комментарии