LINQ查询省略了用户输入

时间:2013-08-06 10:20:41

标签: asp.net-mvc linq razor

所以我有一个包含多个字段的表单,这些字段是在数据库中搜索的标准。

我想使用LINQ来制定查询:

var Coll = (from obj in table where value1 = criteria1 && value2 = criteria2...)

等等。

我的问题是,我不想使用If语句来编写它来检查每个字段是否已填写,我也不想为各种搜索案例(标准1和标准5输入;标准)制定单独的方法2和标准3输入......等)

所以我的问题是:如何在不编写过多代码的情况下实现这一目标?如果我只是在比较中写入查询,如果用户只输入一些值,它会搞砸返回值吗?

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

是的,它会搞砸。

我会选择if,我不明白他们有什么问题:

var query = table;
if(criteria1 != null)
    query = query.Where(x => x.Value1 == criteria1);
if(criteria2 != null)
    query = query.Where(x => x.Value2 == criteria2);

如果您有很多标准,可以使用表达式,字典和循环来减少重复代码。

答案 1 :(得分:0)

在ASP.NET MVC应用程序中,您的用户输入可能来自正在POST到您的服务器的表单。在这种情况下,您可以使用强类型视图,在必须提供的条件上使用带[Required]的视图模型。然后,您将方法包装在if (ModelState.IsValid) { ... }中,并排除了用户未向您提供所需内容的所有情况。

除此之外,如果您可以将标准收集到列表中,则可以对其进行过滤。所以,你可以这样做:

filterBy = userValues.Where(v => v != null);
var Coll = (from obj in table where filterBy.Contains(value1) select obj);

您可以通过为Dictionary(或Lookup非唯一键)包含用户输入的值以及一些标签(enum )它告诉你他们正在过滤哪个字段,然后你可以按照那个标签对它们进行分组,以便为​​每个字段分离出过滤器,然后按照上面的过滤进行过滤。您甚至可以拥有包含其他信息的自定义SearchFilter对象,因此您可以使用包含AND,NOT和OR条件的过滤器...

如果失败了,你可以记住,在你触发对IQueryable的评估之前,它不会命中数据库,所以你可以这样做:

var Coll = (from obj in table where value1 == requiredCriteria select obj);

if(criteria1 != null)
{
    query = query.Where(x => x.Value1 == criteria1);
}
//etc...
if(criteria5 != null)
{
    query = query.Where(x => x.Value5 == criteria5);
}

return query.ToList();

第一行适用任何必须的标准;如果没有任何强制性的,那么它可能只是var Coll = table;。 这将添加将应用的任何标准,任何不会被忽略的标准,您捕获所有可能的组合,并且当您.ToList()时,最后只有一个查询。

答案 2 :(得分:0)

据我所知,如果为了便于阅读,你想集中多个问题;如果我是对的,以下将是一些可能的解决方案

Func<object, object, bool> CheckValueWithAnd = (x, y) => x == null ? true : x==y;

var query = from obj in table 
            where CheckValue(obj.value1, criteria1) && 
                  CheckValue(obj.value2, criteria2) &&
                  ... 
                  select obj;

它很灵活,因为在不同的情况或场景中,您可以按照满足您期望的方式更改功能,而您不需要多个if。

如果要在表达式中使用OR操作数,则需要具有第二个函数

Func<object, object, bool> CheckValueWithOr = (x, y) => x == null ? false : x==y;