简体   繁体   English

在什么时候我需要将查询工作卸载到数据库?

[英]At what point do I need to off-load the work of a query to the DB?

I have a web app, and I'm connecting to a DB with entity framework. 我有一个Web应用程序,并且正在使用实体框架连接到数据库。

To select all Employee records of a particular department, for example, I can quite easily write: 例如,要选择特定部门的所有Employee记录,我可以很容易地写出:

....Employees.Where(o => o.Department == "HR").ToList();

Works fine. 工作正常。 But is it most optimal? 但这是最佳选择吗?

Should this Where clause be incorporated into a stored procedure or view? 应该将此Where子句合并到存储过程或视图中吗? Or does my entity framework code do the job of converting it to SQL anyway? 还是我的实体框架代码执行将其转换为SQL的工作?

We've had performance problems in our team in the past from when people pull records into memory and then do the filtering in .net instead of at a database level. 过去,当人们将记录拉入内存, 然后在.net中而不是在数据库级别进行过滤时,我们的团队就遇到了性能问题。 I'm trying to avoid this happening again so want to be crystal clear on what I must avoid. 我正尝试避免再次发生这种情况,因此想清楚我必须避免的事情。

If Employees is provided by Entity Framework then the Where() will be translated into SQL and sent to the database. 如果Employees是由Entity Framework提供的,则Where()将转换为SQL并发送到数据库。 It is only the point that you materialise the objects does it take the filters you have applied before and turn them into SQL. 只是具体化了对象,才采用了之前应用的过滤器并将它们转换为SQL。 Anything after that point is just plain LINQ to objects. 在那之后的任何事情都只是对象的普通LINQ。

Methods that cause materialisation to happen include things like .ToList() and .ToArray() (there are more, but these two are probably the most common). 导致实现发生的方法包括.ToList().ToArray() (还有更多,但是这两个可能是最常见的)。

If you want to see what is happening on SQL Server, you should open up the SQL Profiler and have a look at the queries that are being sent. 如果要查看SQL Server上发生的情况,则应打开SQL事件探查器,并查看正在发送的查询。

We've had performance problems in our team in the past from when people pull records into memory and then do the filtering in .net instead of at a database level. 过去,当人们将记录拉入内存,然后在.net中而不是在数据库级别进行过滤时,我们的团队就遇到了性能问题。

Just as an addendum to Colin's answer, and to target the quote above, the way to avoid this is to make sure your database queries are fully constructed with IQueryable<T> first, before enumerating the results with a call such as .ToList() , or .ToArray() . 就像Colin答案的附录一样,并针对上面的引用,避免这种情况的方法是先确保使用IQueryable<T>完全构建数据库查询,然后再使用诸如.ToList()类的调用枚举结果。或.ToArray()

As an example, consider the following: 例如,请考虑以下内容:

IEnumerable<Employee> employees = context.Employees;
// other code, before executing the following
var hrEmployees = employees.Where(o => o.Department == "HR").ToList();

The .ToList() will enumerate the results grabbing all of the employees from the context first, and then performing the filtering on the client. .ToList()将枚举结果,首先从上下文中获取所有雇员, 然后在客户端上执行过滤。 This isn't going to perform very well if you've got a lot of employees to contend with, and it's certainly not going to scale very well. 如果您有很多员工要与之抗衡,那么这将无法很好地实现,而且扩展规模肯定也不会很好。

Compare that with this: 与此相比:

IQueryable<Employee> employees = context.Employees;
// other code, before executing the following
var hrEmployees = employees.Where(o => o.Department == "HR").ToList();

IQueryable<T> derives from IEnumerable<T> . IQueryable<T>IEnumerable<T>派生。 The difference between them is that IQueryable<T> has a query provider built in, and the query you construct is represented as an expression tree. 它们之间的区别是IQueryable<T>具有内置的查询提供程序,而您构造的查询表示为表达式树。 That means it's not evaluated until a call that enumerates the results of the query, such as .ToList() . 这意味着只有在枚举查询结果的.ToList().ToList() ,才会对其进行评估。

In the second example above, the query provider will execute SQL to fetch only those employees that belong to the HR department, performing the filtering on the database itself. 在上面的第二个示例中,查询提供程序将执行SQL以仅提取属于HR部门的那些雇员,从而对数据库本身执行过滤。

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

相关问题 显示数据库查询的结果-我需要绑定吗? - Displaying results from DB query - Do I need to bind? 我需要做什么才能使此代码在可移植类库中工作? - What need I do to get this code to work in a Portable Class Library? 在什么时候我需要处理我的自定义WPF用户控件? - At what point I need to do Dispose of my custom WPF User Control? 在什么时候我需要添加X-UA兼容的元标记? - At what point do I need to add the X-UA Compatible meta tags? C#数据库查询应用程序导致数据库服务器停止响应:我可以在数据库服务器上使用哪些工具来识别和研究阻塞点? - C# DB query app causes the DB server to stop responding: What tools can I use on the DB server to identify and study the choke point? 我需要做什么才能使连接字符串在Win XP上正常工作? - What do I need to do in order to make connection string work on win XP? 什么是Fiddler,如何关闭它? - What is Fiddler and how do I turn it off? 如果要使用Telerik的Kendo UI,我需要知道哪些语言? - What languages do I need to know if I want to work with Kendo UI from Telerik? 要让我的网站在移动浏览器上运行,我需要了解什么? - What do I need to know to make my website work on mobile browsers? 这段代码是否做了我需要做的事情 - does this code do what i need it to do
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM