複数のチェックボックスグループでフィルタリングする

私はチェックボックスの値(チェックボックスのタグに保存されているID)に基づいて人のリストを取得したいと思うdatagridviewを持っています。これらのチェックボックスはコード別にビルドされ、2つの異なるグループボックス(sgbExcursionおよびsgbLanguage)に追加されます。

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

1回のエクスカーション(上部のチェックボックス)と1つの言語のみを選択すると、フィルタは正常に動作します。

2つの言語(下位のチェックボックス)を選択すると、 "or"として扱われます。選択した言語のいずれかを話す人だけではなく、選択した言語のいずれかを話す人すべてが表示されます。遠足の同じ問題。

ここでは、選択されたエクスカーションと言語のリストを作成します。

List oExcursionID = new List();

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 oLanguageID = new List();

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();

適切な出力を得るために何を変更できますか?

0

2 答え

問題は、いずれかの言語しか話されていない場合は、 oLanguageID.Contains(oGuideLanguage.LanguageID)という行がtrueを返すということです。

必要な言語と話された言語の共通部分が空であるかどうかを確認する必要があります。

!subset.Except(superset).Any(); のようなものを使うことができます。ここで、subsetは話された言語であり、必要なものをスーパーセットします。

Check this link for more information Determine if a sequence contains all elements of another sequence using Linq

1
追加された

私はあなたがORの代わりにANDを持っていたいと思ったら、あなたは次のような何かをしなければならないと信じています:

内側のクエリの代わりに:

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

次のようなことをしてください:

public IQueryable GetExcustions(IList 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)

そしてあなたは言語に対しても同じことをします。 一連のWhere句がAND文に生成されるとき、Contains(...)はORを生成します(実際にはINを生成しますが、結果は同じです)。

私は大量の解読不能なクエリーステートメントを単純な小さなクエリーステートメントに分割することをもっと勧めます。その後、それらを1つの最終的なクエリにまとめて読みやすい形式にすることができ、バグの修正、維持、修正が容易になります。

1
追加された