Entity Framework编译查询容器是什么?

huangapple go评论71阅读模式
英文:

Entity Framework compiled query container?

问题

我认为以下内容要么是一个好主意,如果是这样的话,可能有人可以指导我实现它的代码。要么是一个愚蠢的主意,如果是这样的话,有人会解释为什么,并帮我避免浪费时间和挫败感。

是否可能为我的每个Entity Framework查询创建一个容器,在第一次调用时编译并执行查询,然后在后续的调用中调用已经编译好的查询?

最好的方式是在使用该查询的方法中直接创建容器,这样在很大程度上是不可见的(使得编写查询与不使用该容器类似)。

英文:

I figure the following is either a good idea, in which case it's likely someone here can point me to the code that implements it. Or a dumb idea in which case someone will explain why and save me the wasted frustration.

Is it possible to create a container for each of my Entity Framework queries where the first time it is called, the query is compiled, and the executed. And then on subsequent times, it calls the now already compiled query?

Preferably in a way that it is created right inline in the method where it's used so it's to a large degree invisible (making crafting the queries similar to not using this container)?

答案1

得分: 3

内部LINQ翻译的工作原理如下:

标准行为:

  1. 翻译器检查缓存中是否存在类似的表达式树的翻译。
  2. 如果找到了翻译,它将使用缓存的SQL和映射器来执行带有给定参数的查询。
  3. 如果没有找到,它将翻译LINQ表达式,生成SQL和映射器,将它们缓存起来,并执行查询。

编译查询行为:

  1. 翻译器检查一个字段是否有预编译的翻译。
  2. 如果找到了翻译,它将使用预编译的SQL和映射器来执行带有给定参数的查询。
  3. 如果没有找到,它将翻译LINQ表达式,生成SQL和映射器,将它们存储在字段中,并执行查询。

这两种算法之间的主要区别在于,编译查询不会在缓存中搜索表达式树的现有翻译,而只会在字段中查找。根据缓存状态和表达式树的复杂性,搜索缓存可能是昂贵的 - 可以参考ExpressionEqualityComparer了解表达式的比较方式。

这就是为什么编译查询更快。

你正在尝试复制标准行为,这将需要再次搜索缓存。在当前的EF Core实现中,这是没有意义的。

英文:

How internally LINQ translation works:

Standard behavior:

  1. The translator checks the cache for an existing translation of a similar expression tree.
  2. If it finds one, it uses the cached SQL and mapper to execute the query with the given parameters.
  3. If not, it translates the LINQ expression, generates the SQL and the mapper, caches them, and executes the query.

Compiled query behavior:

  1. The translator checks a field for a precompiled translation.
  2. If it finds one, it uses the precompiled SQL and mapper to execute the query with the given parameters.
  3. If not, it translates the LINQ expression, generates the SQL and the mapper, stores them in the field, and executes the query.

The main difference between these algorithms is that the compiled query does not search the cache for an existing translation of the expression tree, but only looks in the field. Searching the cache can be costly depending on the cache state and the expression tree complexity - see ExpressionEqualityComparer for how expressions are compared.

That's why compiled queries are faster.

What you are trying to do is replicate the standard behavior, which would require searching the cache again. This does not make sense in the current EF Core implementation.

huangapple
  • 本文由 发表于 2023年8月9日 05:08:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863207.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定