我有一个datagridview,我希望获得一个基于复选框值的人员列表(ID保存在复选框的标签中)。这些复选框是按代码构建的,并添加到2个不同的组框中(sgbExcursion和sgbLanguage)
如果只选择一个偏移(上方复选框)和一种语言,过滤器就可以正常工作。
如果我选择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();
我可以更改什么才能获得正确的输出?
答案 0 :(得分:1)
我相信如果您想要使用AND而不是OR,则必须执行以下操作:
而不是内部查询:
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)
你也为语言做同样的事情。 当在AND语句中生成一系列Where子句时,包含(...)生成OR(实际上它生成IN,但结果是相同的)。
我不能鼓励你将更多难以理解的查询语句分成一组简单的小查询语句。然后,您可以将它们组合成一个可读形式的最终查询,以便更改,维护和修复错误。
答案 1 :(得分:1)
问题是如果只说一种语言,行where oLanguageID.Contains(oGuideLanguage.LanguageID)
将返回true。
您需要检查所需语言与口语的交集是否为空。
您可以使用!subset.Except(superset).Any();
之类的内容,其中子集是口语,并超出所需的语言。
查看此链接以获取更多信息Determine if a sequence contains all elements of another sequence using Linq