当前位置: 首页 > 面试题库 >

LINQ to Entities条件给出奇怪的结果

郎聪
2023-03-14
问题内容

试图在LINQ查询(使用Entityframework)中实现条件创建了奇怪的查询。在某些情况下,即使阈值设置为180秒,这些查询也会超时:

                List<LogEntity> dataList = db.LogEntities.Where(x =>
                x.Source == "Source" &&
                (String.IsNullOrEmpty(from) || x.EventDate >= cFrom) &&
                (String.IsNullOrEmpty(to) || x.EventDate <= cTo) &&
                (String.IsNullOrEmpty(uid) || x.DomainUserLogin == uid) &&
                (String.IsNullOrEmpty(cid) || x.CaseReference == cid) &&
                (String.IsNullOrEmpty(searchtext) || x.Message.Contains(searchtext)))
                .OrderByDescending(y => y.EventDate)
                .Take(500)
                .ToList<LogEntity>();

使用一些不太优雅的if语句,我没有任何问题,查询在几秒钟内返回:

                IQueryable<LogEntity> data = db.LogEntities.Where(x => x.Source == "Source");
            if (!String.IsNullOrEmpty(from))
                data = data.Where(x => x.EventDate >= cFrom);
            if (!String.IsNullOrEmpty(to))
                data = data.Where(x => x.EventDate <= cTo);
            if (!String.IsNullOrEmpty(uid))
                data = data.Where(x => x.DomainUserLogin == uid);
            if (!String.IsNullOrEmpty(cid))
                data = data.Where(x => x.CaseReference == cid);
            if (!String.IsNullOrEmpty(searchtext))
                data = data.Where(x => x.Message.Contains(searchtext));
            data = data.OrderByDescending(x => x.EventDate).Take(500);
            List<LogEntity> dataList = data.ToList<LogEntity>();

条件语句都是从查询字符串传递的,这就是为什么它们有时可能带有值而有时却没有值的原因。

使用三元运算符时会出现相同的问题

...Where(x => truth ? x.something == somevalue : x.something == anothervalue)

关于这些内联条件为何表现如此差的情况,是否有合理的解释?


问题答案:

当您在EF数据库上使用LINQ编写查询时,它们看起来很自然,但是在后台,有一个查询转换器将LINQ查询解析并将其分为两部分:一个在sql服务器上执行,另一个在客户端上仅使用LINQ扩展名执行。

当您使用某些查询翻译器无法转换为SQL的表达式(例如某些.NET函数)时,它将最大限度地减少数据过滤,并且最终可能会将整个数据表下载到客户端并对其进行过滤。

在您写的第一个查询中,您使用(String.IsNullOrEmpty(from) || x.EventDate >=cFrom);“来自”是LogEntities的外部元素,翻译器无法对其值以及如何根据记录进行计算不做任何假设。因此,最有可能的是,您只需将完整的LogEntities下载到客户端,然后将其过滤到客户端。如果记录数量巨大,您将收到超时错误。

在第二个查询中,您加入了简单的表达式Where(x => x.DomainUserLogin ==uid);,这些表达式已明确翻译为sql。因此,您将获得正确的sql查询,该查询可以过滤sql服务器端的大多数记录。

您可以使用SQL事件探查器或VS工具(取决于VS版本,或启用EF中的日志记录来查看已执行的实际查询)。

有关MSDN的一些信息



 类似资料:
  • 问题内容: 因此,当我在Java中使用Doubles进行加法或减法时,它会给我带来奇怪的结果。这里有一些: 如果我加上,它给了我。没错 如果我添加,它会给我(重复s 的数量可能会关闭)。错了 如果我减去,它就会给我(再次,重复的s可能会关闭)。错了 起初我以为这只是将双精度数与十进制值相加的问题,但我错了。以下工作正常: 现在,添加的第一个数字是保存为变量的双精度数,尽管第二个变量从捕获文本。例如

  • 我有一个程序可以读取两个文件(“incompleta.txt”和“completa.txt”),并比较两个文件中是否有相同的名称。其工作原理如下: 它将“completa.txt”中的所有名称存储在ArrayList中 问题是我的“lista.txt”看起来像这样:Image 第二条线完全是混乱和扭曲的。 我的Java代码:

  • 文件2: 主要区别是文件2有[Molpro variables]部分。 我对文件1的输出(注意:预期/期望输出):

  • 问题内容: 我似乎在数组上使用时发现了一个陷阱,但是我找不到解释。本质上,如果我尝试对一个大数组求和,那么我会开始得到荒谬的答案,但这是 无声的, 而且我无法充分理解输出结果,而不是Google的原因。 例如,这完全按预期工作: 为两者提供相同的输出: 但是,这不起作用: 提供以下输出: 在更大的阵列上,有可能获得正面的结果。这是更隐蔽的,因为我可能根本不知道发生了什么不寻常的事情。例如: 给出以

  • 当试图从Hitbox API获取数据时,我得到了一个奇怪的结果。对于一个API的命令,这种情况每次都会发生,而对于另一个API的命令,这种情况只是有时发生。结果差不多是这样(这是我得到的最后一个结果): \U001F\B\0\0\0\0\0\U0003W8SμMU~S N T&N G6C$Z%9IGF[(\U0005\U000F(:6\U000F\B P C\U0015\N\U007F V\U00

  • 我使用Oracle11g(在Red Hat上)。我有一个带有XMLType列的简单常规表: 我使用Oracle SQL Developer(在Windows上): 很管用。我只有一个牢房。我可以双击并下载整个XML文件。 然后我试图以CLOB的形式得到结果: 很管用。我只有一个牢房。我可以双击并看到整个文本和复制它。但有个问题。当我把它复制到剪贴板时,我只得到前4000个字符。似乎在4000位置有