gpt4 book ai didi

C# EF 6.1 - 带委托(delegate)的条件查询的 Strage 行为

转载 作者:行者123 更新时间:2023-11-30 14:28:44 25 4
gpt4 key购买 nike

我注意到 Entity Framework 6.1 有一个非常奇怪的行为。我的目标是有条件地计算一个包含 200 万条记录的表中的一些行。首先,我使用了简单的方法来获得所需的值:

private void SeedsQuery(object o)
{
StatProperty property = o as StatProperty;

using (SteelPoppyContext context = new SteelPoppyContext())
{
property.Value = context.QueuedGames.Count(game => game.IsSeed);
}
}

此代码运行大约 1 秒,并在不使用任何内存的情况下提供所需的结果。现在,我想使用 switch 语句对同一个查询实现更多条件。最简单的方法是使用每次运行查询时提供的委托(delegate)。为了简化我们的案例,我准备了一个简单的示例。

private void SeedsQuery(object o)
{
StatProperty property = o as StatProperty;
Func<QueuedGame, bool> predicate = new Func<QueuedGame, bool>(game => game.IsSeed);

using (SteelPoppyContext context = new SteelPoppyContext())
{
property.Value = context.QueuedGames.Count(predicate);
}
}

此方法应该与上面的方法做完全相同的事情。然而,当我运行这段代码时,查询执行大约需要 1 分钟,并且使用的内存跳到了 1GB。我猜 Entity Framework 正在从数据库中获取所有数据,然后检查条件。对这种行为有什么解释吗?

最佳答案

This method should do exactly the same thing as the one above it

其实一点也不。您编写的方法与您拥有的原始代码不等同。

您的原始代码使用的是 Count 重载 Expression<Func<T, bool>>而不是 Func<T, bool> .因此,如果您想编写等效代码,请确保您这样做:

private void SeedsQuery(object o)
{
StatProperty property = o as StatProperty;
Expression<Func<QueuedGame, bool>> predicate = x => x.IsSeed;

using (SteelPoppyContext context = new SteelPoppyContext())
{
property.Value = context.QueuedGames.Count(predicate);
}
}

请注意 predicate我在示例中使用的变量是 Expression<Func<QueuedGame, bool>>而不仅仅是 Func<QueuedGame, bool> .

现在 EF 将能够构建正确的 SQL,而不是将整个表加载到内存中,然后在浪费所有内容后才计算记录。

关于C# EF 6.1 - 带委托(delegate)的条件查询的 Strage 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28521208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com