Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架计数正在对所有记录进行选择_C#_Entity Framework - Fatal编程技术网

C# 实体框架计数正在对所有记录进行选择

C# 实体框架计数正在对所有记录进行选择,c#,entity-framework,C#,Entity Framework,分析我的代码,因为它需要很长时间来执行,它生成的是一个SELECT而不是计数,并且由于有20000条记录,所以速度非常慢 代码如下: var catViewModel= new CatViewModel(); var catContext = new CatEntities(); var catAccount = catContext.Account.Single(c => c.AccountId == accountId); catViewModel.NumberOfCats =

分析我的代码,因为它需要很长时间来执行,它生成的是一个SELECT而不是计数,并且由于有20000条记录,所以速度非常慢

代码如下:

var catViewModel= new CatViewModel();

var catContext = new CatEntities();

var catAccount = catContext.Account.Single(c => c.AccountId == accountId);

catViewModel.NumberOfCats = catAccount.Cats.Count();
这很简单,但分析器显示的代码是:

exec sp_executesql N'SELECT 
[Extent1].xxxxx AS yyyyy, 
[Extent1].xxxxx AS yyyyy, 
[Extent1].xxxxx AS yyyyy, 
[Extent1].xxxxx AS yyyyy // You get the idea
FROM [dbo].[Cats] AS [Extent1]
WHERE Cats.[AccountId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=7
我以前从未见过这种行为,有什么想法吗

编辑:如果我只是这样做,它是固定的:

catViewModel.NumberOfRecords=catContext.Cats.Where(c=>c.AccountId==AccountId.Count()


我仍然想知道为什么前者不起作用。

大多数情况下,当有人访问实体的子集合时,这是因为记录数量有限,并且可以填充集合。因此,当您访问:

catAccount.Cats
(不管你下一步做什么),它都在填充该集合。然后,您的
.Count()
正在本地内存中集合上运行。问题是你不想那样。现在您有两个选择:

  • 检查您的提供者是否提供了某种机制使其成为查询而不是集合
  • 动态构建查询
  • 改为访问核心数据模型
我很有信心,如果你做到了:

catViewModel.NumberOfRecords =
    catContext.Cats.Count(c => c.AccountId == accountId);

它会很好用的。不太方便?当然但是“工作”比“方便”好。大多数情况下,当有人访问实体的子集合时,这是因为记录数量有限,并且可以填充集合。因此,当您访问:

catAccount.Cats
(不管你下一步做什么),它都在填充该集合。然后,您的
.Count()
正在本地内存中集合上运行。问题是你不想那样。现在您有两个选择:

  • 检查您的提供者是否提供了某种机制使其成为查询而不是集合
  • 动态构建查询
  • 改为访问核心数据模型
我很有信心,如果你做到了:

catViewModel.NumberOfRecords =
    catContext.Cats.Count(c => c.AccountId == accountId);

它会很好用的。不太方便?当然但是“有效”比“方便”好。所以这里有两个完全不同的查询,我想我可以解释为什么会得到不同的结果。让我们看看第一个

// pull a single account record
var catAccount = catContext.Account.Single(c => c.AccountId == accountId);
// count all the associated Cat records against said account
catViewModel.NumberOfCats = catAccount.Cats.Count();
假设
Cats
Account
0..*
关系,并且假设您正在利用框架功能惰性加载外部表,那么您第一次调用
catAccounts.Cats
将导致对所有相关的
Cat
记录进行
选择那个特别的账户。这将导致表被带到内存中,因此对
Count()
的调用将导致对内存集合的
Count
属性进行内部检查(因此不会生成
Count
SQL)

第二个问题

catViewModel.NumberOfRecords = 
    catContext.Cats.Where(c => c.AccountId == accountId).Count();
直接针对
Cats
表(该表将是
IQueryable
),因此对该表执行的唯一操作是
,其中
/
计数
,这两个操作都将在执行前在DB端进行评估,因此显然比第一个更有效

但是,如果您同时需要
Account
Cats
,那么我建议您立即将数据加载到fetch中,这样您就可以预先命中一次

var catAccount = catContext.Account.Include(a => a.Cats).Single(...);

这里有两个完全不同的查询,我想我可以解释为什么会得到不同的结果。让我们看看第一个

// pull a single account record
var catAccount = catContext.Account.Single(c => c.AccountId == accountId);
// count all the associated Cat records against said account
catViewModel.NumberOfCats = catAccount.Cats.Count();
假设
Cats
Account
0..*
关系,并且假设您正在利用框架功能惰性加载外部表,那么您第一次调用
catAccounts.Cats
将导致对所有相关的
Cat
记录进行
选择那个特别的账户。这将导致表被带到内存中,因此对
Count()
的调用将导致对内存集合的
Count
属性进行内部检查(因此不会生成
Count
SQL)

第二个问题

catViewModel.NumberOfRecords = 
    catContext.Cats.Where(c => c.AccountId == accountId).Count();
直接针对
Cats
表(该表将是
IQueryable
),因此对该表执行的唯一操作是
,其中
/
计数
,这两个操作都将在执行前在DB端进行评估,因此显然比第一个更有效

但是,如果您同时需要
Account
Cats
,那么我建议您立即将数据加载到fetch中,这样您就可以预先命中一次

var catAccount = catContext.Account.Include(a => a.Cats).Single(...);

这看起来像是对
Single
的调用。对Single的调用生成:
exec sp_executesql N'SELECT TOP(2)XXX作为YYY,(等)FROM[dbo]。[Account]作为[Extent1],其中[Extent1]。[AccountId]=@p_ulinq_u0',N'@p_ulinq_u0 int',@p_uulinq_uu0=7
Single
立即收回一条记录。
catAccount.Cats
如何声明?指向数据库并按“go”生成模型的标准。从Daniel上面的评论来看,虽然我猜测Single的即时性是问题的原因,但似乎EF可能会在那之后放弃聪明……对我来说,这看起来像是对
Single
的调用。调用Single生成:
exec sp_executesql N'SELECT TOP(2)XXX作为yyyy,(等)From[dbo].[Account]作为[Extent1],其中[Extent1]。[帐户ID]=@p_uulinq_u0',N'@p_ulinq_u0 int',@p_ulinq_u0=7
Single
立即收回一条记录。
catAccount.Cats
是如何声明的?标准指向数据库并按“go”生成模型。尽管我猜测Single的即时性是问题的原因,但从Daniel的上述评论来看,EF可能会在那之后,我开始变得聪明起来。。。