在IQueryable上使用First()方法而不触及数据库

本文关键字:方法 数据库 IQueryable First | 更新日期: 2023-09-27 18:06:21

我正在用一些过滤器构建IQueryable查询表达式。在给定的时刻,我想检查表达式是否有行,并根据结果进行另一个查询。在下面的例子中,Any导致了对数据库的命中,所以我最终对数据库有3次命中。

是否有任何方法可以重用Any的功能,而不会在时间之前触及数据库(类似Where()的所有好处)。

IQueryable<Car> visibleCars = context.Cars.Where(c => c.Status == "V");
IQueryable<Car> invisibleCars = context.Cars.Where(c => c.Status == "I");
IQueryable<Car> c = visibleCars.Any() && invisibleCars.Any() 
                    ? context.Cars.Where(c => c.Status == "x").ToList();

在IQueryable上使用First()方法而不触及数据库

在这种情况下,您应该能够通过将其他查询作为where子句的一部分来获得不产生结果的查询。

IQueryable<Car> c = context.Cars
    .Where(c => c.Status == "x"
        && visibleCars.Any() 
        && invisibleCars.Any())
    .ToList();

作为一种更通用的方法,您通常可以使用GroupBy的一个技巧,在一次往返中执行多个检查:

var interestingData = context.Cars
    .GroupBy(c => false)          // always get one result
    .Select(g => new
    {
        AnyVisibleCars = visibleCars.Any(),
        AnyInvisibleCars = invisibleCars.Any(),
        CarsWithXStatus = visibleCars.Any() && invisibleCars.Any()
            ? g.Where(c => c.Status == "x")
            : g.Where(c => false)
    })
    .Single();