LINQ中的.take方法是否有通配符?

本文关键字:通配符 是否 方法 中的 take LINQ | 更新日期: 2023-09-27 18:16:54

我正在尝试使用LINQ创建一个方法,该方法将从数据库中获取X数量的产品,因此我使用。take方法。

问题是,在我需要取所有产品的情况下,那么是否有一个通配符我可以给。take或其他一些方法,将在DB中给我所有的产品?

另外,如果我执行.TAKE(50),并且数据库中只有10个产品,会发生什么?我的代码看起来像这样:

var ratingsToPick = context.RatingAndProducts
    .ToList()
    .OrderByDescending(c => c.WeightedRating)
    .Take(pAmmount);

LINQ中的.take方法是否有通配符?

你可以根据你的标志将它分离为一个单独的调用:

IEnumerable<RatingAndProducts> ratingsToPick = context.RatingAndProducts
    .OrderByDescending(c => c.WeightedRating);
if (!takeAll)
    ratingsToPick = ratingsToPick.Take(pAmmount);
var results = ratingsToPick.ToList();

如果您不包含Take,那么它将简单地获取所有内容。

请注意,您可能需要将原始查询键入IEnumerable<MyType>,因为OrderByDescending返回IOrderedEnumerable,并且不能从Take调用中重新分配。(或者您可以根据实际代码简单地绕过这个问题)

此外,正如@Rene147所指出的,你应该把你的ToList移到最后,否则它每次都会从数据库中检索所有项,然后OrderByDescendingTake实际上在内存中的对象的List<>上操作而不是将其执行为数据库查询,我认为这是无意的。


关于您的第二个问题,如果您执行Take(50),但只有10个条目可用。这可能取决于您的数据库提供程序,但在我的经验中,它们往往足够聪明,不会抛出异常,只会简单地为您提供可用的项目数量。(我建议您执行一个快速测试,以确保您的具体情况)

您当前的解决方案总是从数据库中获取所有产品。因为你正在呼叫ToList()。从数据库中加载所有产品后,您将在内存中获取第一个N。为了有条件地加载前N个产品,您需要构建查询

int? countToTake = 50;
var ratingsToPick = context.RatingAndProducts
                           .OrderByDescending(c => c.WeightedRating);
// conditionally take only first results
if (countToTake.HasValue)
   ratingsToPick = ratingsToPick.Take(countToTake.Value);
var result = ratingsToPick.ToList(); // execute query