0

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

我想像这样使用 LINQ 来制定查询:

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

等等。

我的问题是,我不想使用 If 语句来检查是否已填写每个字段,也不想为各种搜索案例(条件 1 和条件 5 输入;条件 2 和条件3输入...等)

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

谢谢你的帮助。

4

3 回答 3

3

是的,它会搞砸的。

我会选择ifs,我看不出它们有什么问题:

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

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

于 2013-08-06T10:25:50.030 回答
0

在 ASP.NET MVC 应用程序中,您的用户输入很可能来自正在发布到服务器的表单。在这种情况下,您可以使用具有[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 条件的过滤器...

如果做不到这一点,您可以记住,在您触发对 an 的评估之前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()

于 2013-08-06T10:36:02.973 回答
0

据我了解,为了便于阅读,您希望集中多个 if ;如果我是对的,以下将是一些可能的解决方案之一

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;
于 2013-08-06T13:01:01.490 回答