简体   繁体   English

与SQL相比,EF Linq QUery原因锁定

[英]EF Linq QUery cause lock compared to SQL

I have a simple count query using LINQ and EF: 我有一个使用LINQ和EF的简单计数查询:

var count = (from I in db.mytable
             where xyz
             select I).Count();

the code above shows the query being locked in the database. 上面的代码显示查询已锁定在数据库中。

while the execute sql executes right away: 而execute sql立即执行:

var count = db.SqlQuery<int>("select count(*) from mytable where xyz").FirstOrDefault();

the code above returns immediately. 上面的代码立即返回。

I few have suggested to remove the .ToList() which I did and not difference. 我很少建议删除.ToList(),但没有区别。 One thing is that this only happens on the PROD server. 一件事是,这仅发生在PROD服务器上。 The QA server executes pretty fast as expected. 质量检查服务器执行得非常快。 But the prod server shows that it gets suspended. 但是生产服务器显示它已被挂起。 I suspect this could be a data storage limitation or server related. 我怀疑这可能是数据存储限制或服务器相关。 But wanted to make sure I am not doing something stupid in the code. 但是要确保我没有在代码中做一些愚蠢的事情。

UPDATE: 更新:

One thing I noticed is the first time it execute is takes longer the first time. 我注意到的一件事是,它第一次执行需要更长的时间。 When I set next statement to run it again, it executes immediately. 当我设置下一条语句再次运行时,它立即执行。 Is there a compile of the query the first time? 第一次有查询编译吗?

Because you are calling ToList in the first query and that causes fetching all records from DB and do the counting in memory. 因为您在第一个查询中调用ToList ,这将导致从DB中获取所有记录并在内存中进行计数。 Instead of ToList you can just call Count() to get the same behaviour: 除了ToList您只需调用Count()即可获得相同的行为:

var count = (from I in db.mytable
              where xyz
              select I).Count();

You must not call .ToList() method, because you start retrieve all objects from database. 您不得调用.ToList()方法,因为您开始从数据库中检索所有对象。 Just call .Count() 只需调用.Count()

var count = (from I in db.mytable
             where xyz
             select I).Count(); 

Count can take a predicate. 计数可以使用谓词。 I'm not sure if it will speed up your code any but you can write the count as such. 我不确定它是否会加快代码的速度,但是您可以这样写计数。

var count = db.mytable.Count(x => predicate);

Where predicate is whatever you are testing for in your where clause. where谓词是您在where子句中要测试的内容。

Simple fiddling in LINQPad shows that this will generate similar, if not exactly the same, SQL as above. LINQPad中的简单摆弄显示这将生成与上述类似(如果不完全相同)的SQL。 This is about the simplest way, in terseness of code, that I know how to do it. 就代码简洁而言,这是最简单的方法,我知道该怎么做。

If you need much higher speeds than what EF provides, yet stay in the confines of EF without using inline SQL you could make a stored procedure and call it from EF. 如果您需要的速度比EF所提供的速度高得多,而又不使用内联SQL来限制EF的范围,则可以创建一个存储过程并从EF调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM