当前位置: 首页 > 编程语言 > C#

LINQGeneratesSQLwithRepeatedNestedSelectShare

时间:2023-04-11 10:35:11 C#

这个奇怪的问题(对不起西班牙语,但我的程序是用那个语言的,反正没什么大不了的,只是列或属性名):我是执行正常的LINQToEntities查询以获取UltimaConsulta列表,如下所示:varquery=fromucinbd.UltimasConsultasselectuc;UltmasConsultas是一种观点,顺便说一句。问题是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]为什么LINQ生成嵌套Select?我从视频和示例中了解到,它为这种查询生成正常的SQL选择。我是否必须配置一些东西(实体模型是从向导生成的,所以它是默认配置)?预先感谢您的回答。需要明确的是,LINQtoEntities不会生成SQL。相反,它生成一个ADO.NET规范命令树,而数据库的ADO.NET提供程序(在本例中可能是SQLServer)生成SQL。那么为什么它会生成这个派生表(我认为“派生表”是这里使用的SQL特性的更正确的术语)?因为生成SQL的代码必须为各种LINQ查询生成SQL,所以大多数LINQ查询并不像您显示的那么简单。这些查询往往会选择多种类型的数据(其中很多可能是匿名的而不是命名类型),为了使SQL生成相对合理,将它们分组到每种类型的范围内。另一个问题:你为什么要关心?从性能的角度来看,很容易证明在这个语句中使用派生表是“免费的”。我从填充的数据库中随机选择了一个表并运行了以下查询:SELECT[AddressId],[Address1],[Address2],[City],[State],[ZIP],[ZIPExtension]FROM[VertexRM]。[dbo].[Address]让我们看看成本:现在让我们将其与派生表的查询进行比较: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]以及成本:在这两种情况下,SQLServer仅扫描聚集索引。毫不奇怪,成本几乎相同。让我们看一个稍微复杂一点的查询。我启动了LINQPad并针对同一个表和一个相关表输入了以下查询:City,State=a.State,ZIP=a.ZIP,ZIPExtension=a.ZIPExtension,PersonCount=a.EntityAddresses.Count()}这会生成以下SQL:SELECT1AS[C1],[Project1].[AddressId]AS[AddressId],[Project1].[Address1]AS[Address1],[Project1].[Address2]AS[Address2],[Project1].[City]AS[City],[Project1].[State]AS[状态],[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],(SELECTCOUNT(cast(1asbit))AS[A1]FROM[dbo].[EntityAddress]AS[Extent2]WHERE[Extent1].[AddressId]=[Extent2].[AddressId])AS[C1]FROM[dbo].[Address]AS[Extent1])AS[Project1]通过分析可以看出,Project1是一个匿名类型的投影,Extent1是一个Address表/实体。Extent2是该关联的表。现在没有Address派生表,但是有一个用于projection。不知道大家有没有写过SQL生成系统,其实并不容易。我认为证明LINQtoEntities查询和SQL查询等价物的一般问题是NP-hard,尽管某些特定情况显然要容易得多。SQL是有意图灵不完备的,因为它的设计者希望所有SQL查询都在有限的时间内执行。LINQ,不是这样。简而言之,这是一个很难解决的问题,实体框架及其提供者的组合有时会牺牲一些可读性以支持跨各种查询的一致性。但这不应该是性能问题。它基本上定义了Extent1的组成以及与每个条目关联的变量。然后将实际的数据库表映射到Extent1,以便它可以返回该表的所有条目。这就是您的查询所要求的。只是LINQ不能像您手动那样添加通配符。以上就是C#学习教程:LINQ生成重复嵌套选择SQL的全部内容分享。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: