LINQ 生成具有重复嵌套选择的 SQL

2024-04-25

我对 .NET 实体框架非常陌生,我认为它很棒,但不知怎的,我遇到了这个奇怪的问题(抱歉西班牙语,但我的程序是用那种语言写的,无论如何,这没什么大不了的,只是列或属性名称):我正在执行正常的 LINQ To Entities 查询来获取 UltimaConsulta 列表,如下所示:

var query = from uc in bd.UltimasConsultas
            select uc;

顺便说一句,UltimasConsultas 是一个视图。问题是 LINQ 正在为查询生成以下 SQL:

SELECT 
[Extent1].[IdPaciente] AS [IdPaciente], 
[Extent1].[Nombre] AS [Nombre], 
[Extent1].[PrimerApellido] AS [PrimerApellido], 
[Extent1].[SegundoApellido] AS [SegundoApellido], 
[Extent1].[Fecha] AS [Fecha]
FROM (SELECT 
      [UltimasConsultas].[IdPaciente] AS [IdPaciente], 
      [UltimasConsultas].[Nombre] AS [Nombre], 
      [UltimasConsultas].[PrimerApellido] AS [PrimerApellido], 
      [UltimasConsultas].[SegundoApellido] AS [SegundoApellido], 
      [UltimasConsultas].[Fecha] AS [Fecha]
      FROM [dbo].[UltimasConsultas] AS [UltimasConsultas]) AS [Extent1]

为什么 LINQ 生成嵌套 Select?我从视频和示例中认为它会为此类查询生成正常的 SQL 选择。我是否必须配置某些内容(实体模型是从向导生成的,因此它是默认配置)?预先感谢您的回答。


需要明确的是,LINQ to Entities 不会生成 SQL。相反,它会生成 ADO.NET 规范命令树,并且数据库的 ADO.NET 提供程序(在本例中可能是 SQL Server)生成 SQL。

那么为什么它会生成这个派生表(我认为“派生表”是此处使用的 SQL 功能的更正确术语)?因为生成 SQL 的代码必须为各种 LINQ 查询生成 SQL,其中大多数查询并不像您展示的那么简单。这些查询通常会选择多种类型的数据(其中许多可能是匿名的,而不是命名类型),并且为了保持 SQL 生成相对健全,它们被分组为每种类型的范围。

另一个问题:你为什么要关心?从性能的角度来看,很容易证明该语句中派生表的使用是“免费的”。

我从填充的数据库中随机选择一个表,并运行以下查询:

SELECT [AddressId]
      ,[Address1]
      ,[Address2]
      ,[City]
      ,[State]
      ,[ZIP]
      ,[ZIPExtension]
  FROM [VertexRM].[dbo].[Address]

我们来看看成本:

<StmtSimple StatementCompId="1" StatementEstRows="7900" StatementId="1" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="0.123824" StatementText="/****** Script for SelectTopNRows command from SSMS  ******/&#xD;&#xA;SELECT [AddressId]&#xD;&#xA;      ,[Address1]&#xD;&#xA;      ,[Address2]&#xD;&#xA;      ,[City]&#xD;&#xA;      ,[State]&#xD;&#xA;      ,[ZIP]&#xD;&#xA;      ,[ZIPExtension]&#xD;&#xA;  FROM [VertexRM].[dbo].[Address]" StatementType="SELECT">
  <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" />
  <QueryPlan CachedPlanSize="9" CompileTime="0" CompileCPU="0" CompileMemory="64">
    <RelOp AvgRowSize="246" EstimateCPU="0.008847" EstimateIO="0.114977" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="7900" LogicalOp="Clustered Index Scan" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.123824">

现在让我们将其与使用派生表的查询进行比较:

SELECT 
       [Extent1].[AddressId]
      ,[Extent1].[Address1]
      ,[Extent1].[Address2]
      ,[Extent1].[City]
      ,[Extent1].[State]
      ,[Extent1].[ZIP]
      ,[Extent1].[ZIPExtension]
  FROM (SELECT [AddressId]
          ,[Address1]
          ,[Address2]
          ,[City]
          ,[State]
          ,[ZIP]
          ,[ZIPExtension]
  FROM[VertexRM].[dbo].[Address]) AS [Extent1]

以及成本:

<StmtSimple StatementCompId="1" StatementEstRows="7900" StatementId="1" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="0.123824" StatementText="/****** Script for SelectTopNRows command from SSMS  ******/&#xD;&#xA;SELECT &#xD;&#xA;       [Extent1].[AddressId]&#xD;&#xA;      ,[Extent1].[Address1]&#xD;&#xA;      ,[Extent1].[Address2]&#xD;&#xA;      ,[Extent1].[City]&#xD;&#xA;      ,[Extent1].[State]&#xD;&#xA;      ,[Extent1].[ZIP]&#xD;&#xA;      ,[Extent1].[ZIPExtension]&#xD;&#xA;  FROM (SELECT [AddressId]&#xD;&#xA;          ,[Address1]&#xD;&#xA;          ,[Address2]&#xD;&#xA;          ,[City]&#xD;&#xA;          ,[State]&#xD;&#xA;          ,[ZIP]&#xD;&#xA;          ,[ZIPExtension]&#xD;&#xA;  FROM[VertexRM].[dbo].[Address]) AS [Extent1]" StatementType="SELECT">
  <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" />
  <QueryPlan CachedPlanSize="9" CompileTime="0" CompileCPU="0" CompileMemory="64">
    <RelOp AvgRowSize="246" EstimateCPU="0.008847" EstimateIO="0.114977" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="7900" LogicalOp="Clustered Index Scan" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.123824">

在这两种情况下,SQL Server 只是扫描聚集索引。毫不奇怪,成本几乎完全相同。

让我们看一下slightly更复杂的查询。我启动了 LINQPad,并对同一个表以及一个相关表输入以下查询:

from a in Addresses
select new
{
    Id = a.Id,
    Address1 = a.Address1,
    Address2 = a.Address2,
    City = a.City,
    State = a.State,
    ZIP = a.ZIP,
    ZIPExtension = a.ZIPExtension,
    PersonCount = a.EntityAddresses.Count()
}

这会生成以下 SQL:

SELECT 
1 AS [C1], 
[Project1].[AddressId] AS [AddressId], 
[Project1].[Address1] AS [Address1], 
[Project1].[Address2] AS [Address2], 
[Project1].[City] AS [City], 
[Project1].[State] AS [State], 
[Project1].[ZIP] AS [ZIP], 
[Project1].[ZIPExtension] AS [ZIPExtension], 
[Project1].[C1] AS [C2]
FROM ( SELECT 
    [Extent1].[AddressId] AS [AddressId], 
    [Extent1].[Address1] AS [Address1], 
    [Extent1].[Address2] AS [Address2], 
    [Extent1].[City] AS [City], 
    [Extent1].[State] AS [State], 
    [Extent1].[ZIP] AS [ZIP], 
    [Extent1].[ZIPExtension] AS [ZIPExtension], 
    (SELECT 
        COUNT(cast(1 as bit)) AS [A1]
        FROM [dbo].[EntityAddress] AS [Extent2]
        WHERE [Extent1].[AddressId] = [Extent2].[AddressId]) AS [C1]
    FROM [dbo].[Address] AS [Extent1]
)  AS [Project1]

分析这一点,我们可以看出Project1 is the 投影到匿名类型。Extent1 is the Address表/实体。和Extent2是关联表。现在没有派生表Address,但有一个用于投影。

我不知道你是否曾经编写过 SQL 生成系统,但这并不容易。我相信一般问题证明 LINQ to Entities 查询和 SQL 查询等效是 NP 困难的,尽管某些特定情况显然要容易得多。 SQL 故意是图灵不完备的,因为它的设计者希望所有 SQL 查询都在有限的时间内执行。 LINQ,不是这样的。

简而言之,这是一个非常难以解决的问题,实体框架及其提供者的组合有时确实会牺牲一些可读性以支持广泛查询的一致性。但这不应该是性能问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LINQ 生成具有重复嵌套选择的 SQL 的相关文章

  • ServiceStack 验证并不总是触发

    因此 我尝试使用 RavenDB 和 ServiceStack 构建端到端集成测试套件 但遇到了一个非常奇怪的问题 即验证无法对某些请求运行 这真的很奇怪 我不确定我做错了什么 我正在使用 NCrunch 有时测试通过 有时失败 希望这是一
  • 使 C++ 在模板函数的特定实例化上编译失败

    我正在开发一个具有模板功能的项目 如下所示 template
  • 如何通过 C# 检测字符串中的阿拉伯语或波斯语字符?

    我想检测Arabic or Persian字符串中的字符 例如 在字符串中搜索 15 Aspire ES1 533 C4UH 并返回true 并在字符串中搜索 Aspire ES1 533 C4UH 并返回false string patt
  • 这些比较应该返回什么?

    我有一个使用 string compare string string 对某些值进行排序的应用程序 我不明白的是为什么 1022 比较小于 10 23 而 10 23 比较小于 1024 是否有特定于 值的东西导致了这个结果 string
  • 如何在cmake中添加cuda源代码的定义

    我使用的是 Visual Studio 2013 Windows 10 CMake 3 5 1 一切都可以使用标准 C 正确编译 例如 CMakeLists txt project Test add definitions D WINDOW
  • 将 XML 转换为 JSON 时保留 json:Array 属性

    我有一段 XML 看起来像
  • 同步和异步 API

    我正在开发一个库 它提供一些耗时的服务 我需要每个 API 有两个版本 一个用于同步函数调用 另一个用于异步 图书馆用户应决定使用哪个版本 服务结果可能对于系统继续运行 同步调用 至关重要 可能需要在不同的工作线程中完成相同的操作 因为结果
  • 如何查看某个函数以 3 秒的间隔被调用了多少次?

    我想检查我的函数在 3 秒内可以运行多少次 我写了这段代码 include
  • Compact Framework 3.5 上的 System.Data.SQLite 问题

    我在我的紧凑框架应用程序中使用 sqlite 来记录系统中的事件 我也在使用系统 数据 SQLite http sqlite phxsoftware com 该事件具有描述其发生时间的时间戳 我将此时间戳记作为刻度存储在我的表中 除此列外
  • 如何在 .NET Core 中设置全局环境变量(用户范围或系统范围)

    在完整的 NET中我们可以通过EnvironmentVariableTarget枚举到Environment SetEnvironmentVariable call public enum EnvironmentVariableTarget
  • 如何取消 NetworkStream.ReadAsync 而不关闭流

    我正在尝试使用 NetworkStream ReadAsync 读取数据 但我找不到如何取消调用后的 ReadAsync 作为背景 NetworkStream 由连接的 BluetoothClient 对象 来自 32Feet NET 蓝牙
  • 使用 boost 几何检查两条线是否有交点

    是否可以使用 boost geometry 检查两条线段 每条线段由二维中的两个点给出 是否彼此相交 如果可能的话 boost geometry 是否还允许检查特殊情况 例如另一条线上只有一个点 数字上 或者两条线相等 如果你具体谈论Boo
  • GoogleTest:如何跳过测试?

    使用 Google Test 1 6 Windows 7 Visual Studio C 如何关闭给定的测试 又名如何阻止测试运行 除了注释掉整个测试之外 我还能做些什么吗 The docs https github com google
  • 制作 C# 项目 DLL 和 EXE

    我正在开发一个项目 需要有一个可执行文件以便用户可以运行配置界面和一个可以嵌入其他项目以使用其他一些功能的 DLL 有没有办法让 Visual Studio 同时生成可执行文件和 DLL 而不是每次都手动切换 我同意 TJMonk15 的观
  • 在 C# 中同步闪烁标签

    我创建了一个BlinkingLabel类 源自Forms Label 其中有一个Forms Timer这允许我启用和禁用闪烁效果 我创建了 4 个标签BlinkingLabel类型 我的问题是 如果所有 4 个标签在不同时间闪烁 则闪烁效果
  • 实体框架和多线程

    我有一个处理一些消息的 WCF 服务 我使用 EntityFramework 来检索消息 我将这些消息添加到线程池队列中 然后处理它们 处理完所有消息后 我调用实体框架上的更新来更新消息的状态 在此操作期间 我随机收到错误 在没有先在具有相
  • 我试图使这段代码递归,但由于某种原因它不起作用[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图使这
  • 指针 (*argv[]) 的指针的指针算术?

    我知道foo bar 等于 foo bar 但是什么是 foo bar 等于 例如访问 argv 2 我对这一点的理解有些困惑 我认为可能是这样的 foo bar 但我不确定 如果这是一个简单的答案 我深表歉意 a b 相当于 a b 由于
  • 使用 MVVM 绑定 Xamarin.Forms 中的属性

    我在使用 Xamarin Forms 和 MVVM 制作游戏时遇到问题 游戏中有一艘由用户控制的潜艇 并且有水雷掉落 因此用户必须避开这些水雷 这些地雷是在运行时使用 2 个计时器生成的 因此我用 XAML 中的 CollectionVie
  • SQL 注入在 winform 中有效吗?

    我正在用 C 制作一个 Windows 软件 我读过关于sql injection但我没有发现它适用于我的应用程序 SQL 注入在 winform 中有效吗 如果是的话如何预防 EDIT 我正在使用文本框来读取用户名和密码 通过使用 tex

随机推荐

  • 使用 Appcompat v7 的抽屉式导航 - ?android:attr 标签的问题

    我在我的项目中使用操作栏和导航抽屉 使用 appcompat v7 和 v4 我已经添加了 appcompat v7 和资源 以下是我的导航抽屉列表的文本视图 直接取自位于以下位置的 Android 示例应用程序 创建抽屉式导航 http
  • C#:通过反射检索和使用 IntPtr*

    我目前正在编写一些代码 这些代码反映了从调用本机 dll 中编组回来的结构 某些结构包含指向以 null 结尾的指针数组的 IntPtr 字段 这些领域需要特殊处理 当反映结构时 我可以识别这些字段 因为它们是由自定义属性标记的 以下说明了
  • ant-找不到符号@Test

    我正在尝试编译以下仅包含一个函数的类 公共类测试注释 Test public void testLogin System out println Testing Login 当我将文件作为 JUNIt 运行时 它可以工作 但是当我尝试从 b
  • 计算 a*a mod n 且不溢出

    I need to calculate a a mod n but a is fairly large resulting in overflow when I square it Doing a n a n n doesn t work
  • 树莓派蓝牙4.0连接

    我正在尝试使用 CoreBluetooth 蓝牙 4 0 通过 iPhone 连接到 Raspberry Pi 我已经发现了该设备并使用以下代码发出连接请求 if peripheral self foundPeripheral NSLog
  • Javascript ResizeObserver 意外触发

    Why the ResizeObserver类总是首先执行处理程序observe 尝试在 Chrome 开发工具上执行以下代码 new ResizeObserver gt console log resize detected observ
  • 从 asp.net 中的 dataSet 获取单个值

    我正在执行查询以从 tbl message 表获取 Title 和 RespondBY 我想在对转发器进行数据绑定之前解密标题 在进行数据绑定之前如何访问标题值 string MysqlStatement SELECT Title Resp
  • jQuery 显示/隐藏/切换有效,但没有保持应有的状态 - 它恢复到原始状态

    我尝试使用 jQuery 显示 隐藏常见问题解答 这个想法是列出所有问题 只有当用户想要查看答案时 他们才会单击问题 看起来像链接 然后答案就会变得可见 它有点有效 只不过一旦单击答案就会恢复到其原始状态 在这种情况下 这意味着当我单击问题
  • 对一列进行唯一约束,排除其他列中具有相同值的行

    我想向列添加唯一键value但我必须忽略列中具有相同值的行value and header id 例如 考虑这个表 id header id value 1 1 a 2 1 a 3 2 a 因此 第 1 行和第 2 行指向同一个对象 并且唯
  • 您可以在不同的 OSGi 包中拥有 JSF 自定义组件吗?

    有人同时使用过 OSGi 和 JSF 吗 我问这个问题是因为 JSF 使用类加载器魔法来查找自定义组件 来自教程 重点是我的 这个配置文件最终会 是 META INF faces config xml 中 代表此的 jar 文件 成分 JS
  • 如何在没有 Intent 的情况下以编程方式拨打电话

    我是 Android 新手 我想在不使用intent 我知道这段代码 Intent intent new Intent Intent ACTION CALL intent setData Uri parse tel bundle getSt
  • 如何将焦点设置到重复控件内的编辑框?

    我想将焦点设置为 将光标置于重复控件中的编辑框 最后一个 重复位于面板 panelRep 内 然后我在面板外面有一个按钮 这是几乎可以工作的按钮的客户端代码 焦点已设置 字段周围的蓝色边框 但光标未放置在字段中 用户仍必须单击该字段才能写入
  • C++ 中可重用的成员函数

    我正在使用这个成员函数来获取指向对象的指针 virtual Object Create return new Object 它是虚拟的 所以我可以获得指向派生对象的指针 现在我这样做 virtual Object Create return
  • 如何在 Google Cloud Platform (GCP) 中测试 Cloud Function?

    我一直在试图寻找这个问题的答案 但无法在任何地方找到它 在 Google Cloud Platform 控制台的 Cloud Functions 部分上 有一个部分标题为 测试 但我不知道应该在此处放置什么来测试该函数 即语法 I have
  • 设计和处理闪光灯

    我正在将 Devise 3 1 1 与 Rails 3 一起使用 并且我的布局中有以下闪存处理代码 我登录我的应用程序 Flash 说 Signed in successfully 然后注销 然后错误登录并闪烁显示 Signed out s
  • iPhone:如何编写减少倒数计时器的代码?

    我想使用显示倒计时器UILabel将从 5 开始并且每秒减少 1 like 5 4 3 2 1 最后当达到 0 时隐藏标签 我尝试使用它进行编码NSTimer scheduledTimerWithTimeInterval但惨败 请帮我 我只
  • 使用 Jest 模拟 Es6 类

    我正在尝试使用接收参数的构造函数来模拟 ES6 类 然后使用 Jest 模拟该类上的不同类函数以继续测试 问题是我找不到任何有关如何解决此问题的文档 我已经看过了这个帖子 https stackoverflow com questions
  • Java:为 Polynomial 类创建 toString 方法

    public String toString String mytoString if a equals 0 mytoString a toString x 2 if b equals 0 mytoString b toString x i
  • 我什么时候应该按值传递或返回结构体?

    在 C 中 结构体可以按值传递 返回 也可以按引用 通过指针 传递 返回 普遍的共识似乎是前者可以应用于小型结构 在大多数情况下不会受到惩罚 看在任何情况下 直接返回结构是一种好的做法吗 https stackoverflow com a
  • LINQ 生成具有重复嵌套选择的 SQL

    我对 NET 实体框架非常陌生 我认为它很棒 但不知怎的 我遇到了这个奇怪的问题 抱歉西班牙语 但我的程序是用那种语言写的 无论如何 这没什么大不了的 只是列或属性名称 我正在执行正常的 LINQ To Entities 查询来获取 Ult