c# - 使用 Func 和 OrderByDescending 时 Linq 查询花费的时间太长

标签 c# .net entity-framework linq

考虑这段代码:

public List<Clients> GetFilteredClients(DateTime? FromDate = null, 
                                        DateTime? ToDate = null,    
                                        int? fromLocationType = null, 
                                        int? toLocationType = null)
{
    Func<Clients, bool> fromDateFilter = f => true;
    if (FromDate.HasValue)
    {
        fromDateFilter = z => z.Insert_Date.Value.Date >= FromDate.Value.Date;
    }

    Func<Clients, bool> toDateFilter = f => true;
    if (ToDate.HasValue)
    {
        toDateFilter = z => z.Insert_Date.Value.Date <= ToDate.Value.Date;
    }

    Func<Clients, bool> fromLocationTypeFilter = f => true;
    if (fromLocationType.HasValue)
    {
        fromOrgFilter = z => z.LocationTypeId >= fromLocationType.Value;
    }

    Func<Clients, bool> toLocationTypeFilter = f => true;
    if (toLocationType.HasValue)
    {
        toLocationTypeFilter = z => z.LocationTypeId <= toLocationType.Value;
    }

    var filtered = DB_Context.Clients
        .Where(fromDateFilter)
        .Where(toDateFilter)
        .Where(fromLocationTypeFilter)
        .Where(toLocationTypeFilter)
        .OrderByDescending(k => k.Id)
        .Take(1000)
        .ToList();
    return filtered;
}

我在数据库中有大约 100K 条记录,我只需要满足以下要求的前 1000 条:

.Where(fromDateFilter)
.Where(toDateFilter)
.Where(fromLocationTypeFilter)
.Where(toLocationTypeFilter)

但是执行时间仍然需要大约 10 秒。

知道为什么吗?

最佳答案

您必须使用 Expression<Func<...>>而不是 Func<...> .当您使用 Func , 只有可枚举的方法可以用于可查询的,在这种情况下意味着您首先将所有内容下载到内存中,然后进行过滤。如果你切换到 Expression<...> ,O/RM 将在数据库服务器上进行过滤,而不是在您的应用程序中。

此外,还有更好的方法来完成您正在做的事情。例如,您可以像这样构建条件:

var query = DB_Context.Clients.AsQueryable();

if (FromDate.HasValue) query = query.Where(...);
if (ToDate.HasValue) query = query.Where(...);

...

return query.OrderByDescending(k => k.Id).Take(1000).ToList();

当然,这意味着您使用的任何数据库提供商都必须能够支持您尝试执行的过滤类型 - 您需要查阅文档。

关于c# - 使用 Func 和 OrderByDescending 时 Linq 查询花费的时间太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33102832/

相关文章:

c# - 如何显示日期?

c# - Directory.EnumerateFiles 异常

c# - 同时用户在数据绑定(bind) DataGridView 中进行更改时出现问题

c# - Delphi Pipes.PAS 与 .NET 命名管道不兼容?

c# - 创建协程以淡出不同类型的对象

c# - .Net 中用于 MySQL 数据库的日期时间格式

asp.net - 身份和自定义表之间的多对多关系。 EF7-代码优先

C# - EF 6 - MySQL : Error when calling method from unit test method

c# - 在列表中查找重复项

c# - 如何检查 bitArray 包含任何真值或任何假值?