我是使用实体框架(核心2.0.1)的新手,对我的理解,LINQ表达式通过实体框架映射到供应商特定的SQL查询,如
from actor in db.Actors
where actor.Name == "Madonna"
|| actor.Name == "Bruce Lee"
select actor
映射到
SELECT *
FROM Actors
WHERE Name = 'Madonna'
OR Name = 'Bruce Lee';
我有read某处引用
EF / Core转换查询方法在SQL中调用WHERE子句,并将谓词表达式树(同样,不是谓词函数)转换为WHERE子句中的条件。
假设我想在匹配actor名称时不区分大小写,并允许在actor名称之前和之后使用空格。我需要使用正则表达式。我试图做以下
public static bool Contains1(Actor actor)
{
bool result;
ISet<string> RegexStrSet = new HashSet<string>(
new String[]{
@"Bruce\s+Lee",
@"Madonna"
}
);
result = false; //assumed
for (IEnumerator<String> criteria = RegexStrSet.GetEnumerator(); criteria.MoveNext() && !result;)
{
if (Regex.Match(actor.Name, @"\s*" + criteria.Current + @"\s*", RegexOptions.IgnoreCase).Success)
{
result = true;
}
}
return result;
}
static void Main(string[] args)
{
using (var db = new ActorDbContext())
{
Predicate<Actor> functPred1 = new Predicate<Actor>(Contains1);
if ((from actor in db.Actors
where functPred1(actor)
select actor).Count() == 0
)
{
...
这确实有效。我现在假设谓词没有映射到哪里但是在返回表的行时运行,所以现在数据库SQL查询
SELECT *
FROM Actors
我的问题是,实体框架有三个选项来检索行。是吗
- 如果表太大,请检索整个表并抛出内存运行时异常。
- 尽可能多地检索它并再次执行它,直到整个表被评估。
- 一次检索并评估一行
如果它试图一次性检索整个表格,我该怎么办才不会崩溃。
编辑: 我复制并连接了Dixin's Application side logging以查看下面列出的下划线查询被发送到服务器的内容。注意:仅包含最相关的日志片段。
foreach (Actor actor in (from actor in db.Actors
where actor.Name == "Madonna"
|| actor.Name == "Bruce Lee"
select actor)){ }
日志输出摘录:
2018-01-20T21:56:17.0846048+00:00 Information 20101 Microsoft.EntityFrameworkCore.Database.Command
Executed DbCommand (57ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [actor].[Id], [actor].[AcademyWinner], [actor].[Age], [actor].[Name]
FROM [Actors] AS [actor]
WHERE [actor].[Name] IN (N'Madonna', N'Bruce Lee')
和
foreach (Actor actor in (from actor in db.Actors
where functPred1(actor)
select actor)){ }
日志输出摘录:
2018-01-20T21:56:17.1878434+00:00 Warning 20500 Microsoft.EntityFrameworkCore.Query
The LINQ expression 'where Invoke(__functPred1_0, [actor])' could not be translated and will be evaluated locally.
2018-01-20T21:56:17.2269410+00:00 Information 20101 Microsoft.EntityFrameworkCore.Database.Command
Executed DbCommand (8ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [actor].[Id], [actor].[AcademyWinner], [actor].[Age], [actor].[Name]
FROM [Actors] AS [actor]
所以似乎从数据库服务器检索整个表。实体框架只能一次只检索表的一个子集,评估行上的谓词函数并继续,直到查询测试了表中的每一行以防止内存耗尽,这不是更聪明吗运行时异常,而不是其他应用程序的占用RAM。
答案 0 :(得分:0)
我的问题是,实体框架有三种选择 将检索行。是吗
- 如果表太大,请检索整个表并抛出内存运行时异常。
- 尽可能多地检索它并再次执行它,直到整个表被评估。
- 一次检索并评估一行
我不认为你会在没有某种过滤器/限制的情况下调用EF上下文,当然如果你的机器没有运行它的规格,程序也会崩溃。但是,如果您练习良好的实体关系模型,我认为您不会在一个表中获得超过4GB的数据。
不要担心在一个表中获取所有行(因为你不会发现自己首先这样做了。)
以下是一些补充有关EF表现的想法的链接: