2012-02-06 2 views
0

У меня есть datagridview, где я хочу получить список лиц, построенных на значениях флажков (идентификаторы сохранены в теге флажка). Эти флажки строят кодом и добавляют в 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(); 

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

ответ

1

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

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

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.

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

1

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

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

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

Проверьте эту ссылку за дополнительной информацией Determine if a sequence contains all elements of another sequence using Linq

Смежные вопросы