在ASP.Net MVC中,我应该在实现搜索时将我的where子句添加到我的ienumerable或iqueryable中吗?

时间:2013-11-13 19:47:05

标签: c# asp.net-mvc ienumerable iqueryable entity-framework-6

我想知道用户何时访问我网站上的表格的索引页面并使用搜索功能我应该将where子句添加到ienumerable或iqueryable?我知道两者都可以完成,哪一个更有效,我可以在iqueryable中添加自定义搜索字符串扩展吗?

4 个答案:

答案 0 :(得分:0)

将它添加到IQueryable会将其添加到进入数据库的查询,因为它是与DB的实时连接的一部分。

将其添加到IEnumerable(不是IQueryable类型)将在查询执行后在内存中进行过滤。

如果你正在处理潜在的IQueryable,在这两种情况下,我都怀疑会有什么不同。 但是,我建议在sql探查器中查看生成的查询,以确保您正在执行预期的查询。

答案 1 :(得分:0)

我将它添加到你的IQueryable以防万一,但由于两者都是接口,它可能并不重要。如果您的IEnumerables总是IQueryables,您仍然可以获得在数据库上运行查询的好处,而不是在数据库返回结果后。

答案 2 :(得分:0)

IQueryableIEnumerable就是所谓的“接口”。接口定义了实际对象应该能够响应的API,同时允许实际类型(读取:对象实现的类)的一定程度的可变性。只要类型实现了接口,一切都可以工作,并且你可以(大多数情况下)将一种类型换成另一种类型,只要它们都实现相同的接口。

尽管如此,IQueryable实际上是IEnumerable的延伸,所以就你在这里所说的而言,它们实际上是同一个东西。换句话说,它不是关于从数据库返回的对象集是否转换为IQueryableIEnumerable;在任何一种情况下,查询可能已经或可能尚未执行,因为两个接口都没有规定必须执行查询。重要的是你是否在代码中做了一些会导致查询被执行的东西:诸如转换为列表(.ToList())或迭代结果集(for,{{运行计数也将执行查询,但原因略有不同(您将向数据库而不是SELECT发出COUNT查询)。

道德是你只需要注意代码的哪些部分实际上会导致查询被执行,并确保在此之前发生任何查询更改。

答案 3 :(得分:0)

根据您对情况的描述,我会使用IQueryable来运行您的Where(),然后将其转换为List<SomeViewModel>以将其返回到您的网页。执行此操作将推迟对数据库执行查询,直到您对其进行优化以返回您所需的内容。

我使用普通的旧变量代替自定义搜索字符串扩展,并根据传入的内容削减我的对象。因此,如果您正在编写一个接收firstNamelastName的搜索控制器您可以执行以下操作的参数:

IQueryable<User> users = Context.Users;

if (firstName != null)
    users = users.Where(x => x.FirstName == firstName);

if(lastName != null)
    users = users.Where(x => x.LastName == lastName);

List<SearchResultViewModel> model = users.Select(x => new SearchResultViewModel
        {
            FirstName = x.FirstName,
            LastName = x.LastName,
            JobTitle = x.JobTitle
            // and so forth for whatever fields you need to return...
        }).ToList();
        // The ToList() will cause the query to be 
        // evaluated and executed.

当然,您应该检查以确保至少有一个搜索字段中包含某些内容,因此您不会返回整个表格的数据。从这里你可以装备它来接受分页变量,应用排序,各种有趣的东西。