Фильтр по нескольким группам флажков - PullRequest
0 голосов
/ 06 февраля 2012

У меня есть сетевое представление, в котором я хочу получить список людей, основанных на значениях флажков (идентификаторы сохраняются в теге флажка). Эти флажки создаются по коду и добавляются в 2 разных групповых блока (sgbExcursion и sgbLanguage)

!(http://www.iwva.be/images/ss/ss_listguides.jpg)

Фильтр отлично работает, если вы выберете только одну экскурсию (верхние флажки) и только один язык.

Если я выберу 2 языка (нижние флажки), он будет рассматриваться как "или". Показаны все лица, говорящие на одном из выбранных языков, а не только лица, говорящие на обоих выбранных языках. Та же проблема с экскурсиями.

Здесь я строю список выбранных экскурсий и языков:

List<int> oExcursionID = new List<int>();

foreach (Control oControl in sgbExcursion.Controls)
{
    if (oControl.GetType() == typeof(CheckBox))
    {
        CheckBox oCheckBox = (CheckBox)oControl;
        if (oCheckBox.Checked)
        {
            oExcursionID.Add(int.Parse(oCheckBox.Tag.ToString()));
        }
    }
}

List<int> oLanguageID = new List<int>();

foreach (Control oControl in sgbLanguage.Controls)
{
    if (oControl.GetType() == typeof(CheckBox))
    {
        CheckBox oCheckBox = (CheckBox)oControl;
        if (oCheckBox.Checked)
        {
            oLanguageID.Add(int.Parse(oCheckBox.Tag.ToString()));
        }
    }
}

Здесь я пытаюсь получить правильные значения из базы данных. И языки, и экскурсии сохраняются в реляционной таблице (Person_ID, Exursion_ID) или (Person_ID, Language_ID).

var vGuides = (from oGuideToAdd in clsApplication._oDBConnection.tblGuides
                where ((from oGuideExcursion in clsApplication._oDBConnection.tblGuideExcursions
                        where oExcursionID.Contains(oGuideExcursion.ExcursionID)
                        select oGuideExcursion.GuideID).Contains(oGuideToAdd.ID)
                && (from oGuideLanguage in clsApplication._oDBConnection.tblGuideLanguages
                    where oLanguageID.Contains(oGuideLanguage.LanguageID)
                    select oGuideLanguage.GuideID).Contains(oGuideToAdd.ID))
                select oGuideToAdd).ToList();

Что я могу изменить, чтобы получить правильный вывод?

Ответы [ 2 ]

1 голос
/ 06 февраля 2012

Проблема в том, что строка where oLanguageID.Contains(oGuideLanguage.LanguageID) вернет true, если говорят только на одном из языков.

Вам нужно будет проверить, является ли пересечение требуемых языков с разговорными языками пустым.

Вы можете использовать что-то вроде !subset.Except(superset).Any();, где подмножество - это разговорные языки и заменять необходимые.

Проверьте эту ссылку для получения дополнительной информации Определите, содержит ли последовательность все элементы другой последовательности, используя Linq

1 голос
/ 06 февраля 2012

Я полагаю, что если вы хотите иметь И вместо ИЛИ, вам придется сделать что-то вроде:

вместо вашего внутреннего запроса:

from oGuideExcursion in clsApplication._oDBConnection.tblGuideExcursions
where oExcursionID.Contains(oGuideExcursion.ExcursionID)
select oGuideExcursion.GuideID

сделать что-то вроде:

public IQueryable<Excursion> GetExcustions(IList<int> excursionIds) 
{
    var query = clsApplication._oDBConnection.tblGuideExcursions;
    foreach(var id in excursionIds)
    {
        query = query.Where(x=>x.ExcursionId == id);
    }
    return query;
}

тогда вы используете его как:

var guideIdsFromExcustions = GetExcursions(oExcursionsID)
                                .Select(x=>x.GuideID)
                                .Distinct()
                                .ToList(); //ToList is probably optional

from oGuideToAdd in clsApplication._oDBConnection.tblGuides
where guideIdsFromExcustions.Contains(oGuideToAdd.GuideID)

И вы делаете то же самое для языков.Идея состоит в том, что Contains (...) генерирует OR (на самом деле он генерирует IN, но результат тот же), когда ряд предложений Where генерируется в операторах AND.

Я не могу вас больше поощрятьразделить огромные нечитаемые операторы запросов на набор простых маленьких.Затем вы можете объединить их в один итоговый запрос в удобочитаемой форме, чтобы было легко изменять, поддерживать, исправлять ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...