尝试构建一个查询以按以下方式过滤数据的工作正常,返回过滤的所有过滤器都在FilterNamesAndValues参数中。
GetAllUsersFiltered(..., Dictionary<string,string> FilterNamesAndValues)
{
....
List<DataContracts.IUser> lstUsers = new List<DataContracts.IUser>();
....
var query = from u in lstUsers select u;
string firstName = string.Empty;
FilterNamesAndValues.TryGetValue("FirstName", out firstName);
query = query.Where(u => u.FirstName == firstName);
string company = string.Empty;
FilterNamesAndValues.TryGetValue("Company", out company);
query = query.Where(u => u.CompanyName == company);
....
return query.ToList();
}
但是下面的例子不起作用,我看不出原因:
GetAllUsersFiltered(..., Dictionary<string,string> FilterNamesAndValues)
{
....
List<DataContracts.IUser> lstUsers = new List<DataContracts.IUser>();
....
var query = from u in lstUsers select u;
foreach (KeyValuePair<string, string> kv in FilterNamesAndValues)
{
if (kv.Value != null)
{
switch (kv.Key)
{
case "FirstName":
query = query.Where(u => u.FirstName == kv.Value);
break;
case "Company":
query = query.Where(u => u.CompanyName == kv.Value);
break;
}
}
}
return query.ToList();
}
在应用程序遇到第一个switch case之后,我可以执行query.ToList()并在那里看到一行。但是当执行绕过第二个过滤器的循环时,query.ToList()什么都不返回。查询不会像第一个示例中那样连续过滤,更糟糕的是,过滤条件实际上已经丢失。对此可能有一个明显的解释,但现在我看不到它。
答案 0 :(得分:4)
问题是你在foreach中关闭kv
,但查询是使用延迟执行执行的。这会导致它关闭错误的值。有关正在发生的事情的详细信息,我建议Eric Lippert的帖子标题为“Closing over the loop variable considered harmful”。
您可以通过临时解决此问题:
foreach (KeyValuePair<string, string> kvOriginal in FilterNamesAndValues)
{
// Make a temporary in the correct scope!
KeyValuePair<string, string> kv = kvOriginal;
if (kv.Value != null)
{
switch (kv.Key)
{
case "FirstName":
query = query.Where(u => u.FirstName == kv.Value);
break;
case "Company":
query = query.Where(u => u.CompanyName == kv.Value);
break;
}
}
}