【问题标题】:Is there a wildcard for the .Take method in LINQ?LINQ 中的 .Take 方法是否有通配符?
【发布时间】:2013-05-29 18:49:07
【问题描述】:

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

问题是,在我需要获取所有产品的情况下,我可以为 .TAKE 提供一个通配符或其他可以将所有产品带到数据库中的方法吗?

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

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

【问题讨论】:

  • 您的示例实际上是从数据库中获取所有值,而不考虑获取。将您的 ToList() 移动到执行拍摄之后。

标签: c# linq entity-framework


【解决方案1】:

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

IEnumerable<RatingAndProducts> ratingsToPick = context.RatingAndProducts
    .OrderByDescending(c => c.WeightedRating);

if (!takeAll)
    ratingsToPick = ratingsToPick.Take(pAmmount);

var results = ratingsToPick.ToList();

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

请注意,您可能需要将原始查询键入为IEnumerable&lt;MyType&gt;,因为OrderByDescending 返回一个IOrderedEnumerable,并且不能通过Take 调用重新分配。 (或者您可以根据您的实际代码酌情解决此问题)

另外,正如@Rene147 指出的那样,您应该将您的ToList 移到末尾,否则它将每次都从数据库中检索所有 项,然后OrderByDescendingTake实际上对内存中的对象List&lt;&gt; 进行操作将其作为数据库查询执行,我认为这是无意的。


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

【讨论】:

  • 我会检查 pAmmount 的值,例如:if(pAmmount == -1)。然后您可以生成自己的通配符(在我的示例中为-1)。
  • @ScottChamberlain 这可能是合理的;我不知道 MaG3Stican 如何确定“通配符”何时适用。而-1 是一个神奇的数字,所以我不想假设这种情况。
  • 我的 linq2SQL 是新手级别的,我只做 Linq2Objects,但ToList() 不是让这个成为 Linq2Objects 查询并且不再依赖于数据库提供者吗?编辑:呸,那是两次,现在我问你一些事情,当我点击“添加评论”时,你立即编辑你的问题澄清它。
  • @ScottChamberlain 是的,在这种情况下确实如此(我错过了),但我只能假设这是提问者无意的。我更新了我的答案以解决这个问题。
  • @ScottChamberlain 哈哈,对不起。猜猜我们伟大的思想都一样! (或者也许我们这些傻瓜很少有不同?)
【解决方案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

【讨论】:

    猜你喜欢
    • 2012-01-18
    • 2011-04-09
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多