5

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

问题是,在我需要带走所有产品的情况下,我可以给 .TAKE 通配符或其他可以将所有产品带入数据库的方法吗?

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

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

2 回答 2

6

您可以根据您的标志将其分离为单独的调用:

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移到最后,否则它将每次都从数据库中检索所有OrderByDescending项目,然后Take实际上是List<>在内存中的一个对象上进行操作,而不是将其作为数据库查询执行,我假设是无意的。


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

于 2013-06-03T15:02:18.667 回答
2

您当前的解决方案总是从数据库中获取所有产品。因为你在打电话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
于 2013-06-03T15:08:06.960 回答