Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 选择导航属性为空的条目的最佳方法_C#_Linq_Entity Framework - Fatal编程技术网

C# 选择导航属性为空的条目的最佳方法

C# 选择导航属性为空的条目的最佳方法,c#,linq,entity-framework,C#,Linq,Entity Framework,我遇到了一点性能问题。我得到了以下数据库模型。 我希望选择Entity2中所有在Entity1中没有外键的条目,换句话说,导航属性必须为null 我提出了以下LINQ查询context.Entity2Set.Where(x=>x.Entity1==null)和它的工作,但它的速度很慢。所以我想知道是否有更好(更快)的方法(除了索引)来选择条目 最后,我想从Entity4中选择条目,因此性能是一个问题。您已经说过 无索引 但对于这个问题,这将是一个错误。索引几乎会立即找到所有空引用。您查询的是关

我遇到了一点性能问题。我得到了以下数据库模型。

我希望选择Entity2中所有在Entity1中没有外键的条目,换句话说,导航属性必须为null

我提出了以下LINQ查询
context.Entity2Set.Where(x=>x.Entity1==null)和它的工作,但它的速度很慢。所以我想知道是否有更好(更快)的方法(除了索引)来选择条目

最后,我想从Entity4中选择条目,因此性能是一个问题。

您已经说过

无索引


但对于这个问题,这将是一个错误。索引几乎会立即找到所有空引用。

您查询的是关系中的主体(
Entity2
),而不是依赖项(
Entity1
)。这意味着外键在表
Entity1
中,生成的SQL查询不仅仅是对表
Entity2
中的列值的查询。为了获得所需的结果,SQL查询必须连接(通过
左外部连接
)这两个表

如果是一对多关系,您的查询类似于:“获取所有没有订单项的订单”。这不能通过单独检查
order
表来实现,因为外键位于table
OrderItem
中,并且查询必须连接两个表。实际上,在本例中,可以通过索引表
OrderItem
中的外键列来提高查询的性能

不幸的是,在您的示例中,您无法再通过索引列来改进查询,因为您有一对一的关系(而不是一对多)。由于EF的一对一关系始终是共享主键关联,因此表
Entity1
中的外键同时是其主键
Id

这意味着您的外键列已经被索引——即通过表
Entity1
中的聚集主键索引

生成的SQL查询如下所示:

选择
[Extent1].[Id]作为[Id],
[Extent1].[OtherColumn]作为[OtherColumn]
来自[dbo]。[Entity2]作为[Extent1]
左外部联接[dbo].[Entity1]为[Extent1].[Id]=[Extent2].[Id]上的[Extent2]
左外部联接[dbo].[Entity1]作为[Extent2].[Id]=[Extent3].[Id]上的[Extent3]连接
其中[Extent3].[Id]为空
如您所见,这些表由索引的
Id
列连接。第二个冗余的
左外部联接是实体框架的SQL生成中的一个缺陷,该缺陷对EF<5.0有效。我不确定它是否在EF>=5.0中解决。我不知道这是否真的对查询性能有影响,因为该行通过同一列将表本身连接起来,所以我希望SQL查询优化器能够识别它,并忽略执行计划中的行

本质上:您的LINQ查询很好,即使不向列添加任何附加索引,也无法提高性能


然而,我的建议是找出真正慢的是什么。它确实是SQL查询,还是从LINQ查询到SQL的转换,或者可能是返回结果集的对象物化,等等。?我要做的第一步是将生成的SQL查询粘贴到SQLServerManagementStudio中,并查看性能如何。即使您不会更改LINQ查询,也可能有其他机会来提高性能。

在调试模式下悬停在LINQ查询上,将允许您查看将要生成和执行的实际SQL。查看这一点可能会让您了解Linq查询实际上在做什么,从而帮助您解决性能问题。这应该是一个快速查询。听起来外键列需要索引。为什么不需要索引?每个表中有多少记录?10、100、1000、10000、100000、1000000、更多?@retailcoder我不是不想要索引,我只是想知道是否有其他方法可以改进查询。所以我这样说是为了避免默认的索引答案:)没有
NULL
引用,因为FK在
Entity1
中,而不是
Entity2
中。问题是导航属性必须为NULL。LINQ查询中使用的导航属性不是表示外键端的导航属性,而是反向属性。(您可以从图中的
0..1
1
,即
Entity2
是主要的)如果表
Entity1
中不存在引用表
Entity2
的记录,而不是FK为
null
时,则为
null
。(在这种情况下,因为FK是PK,这是一对一关系,所以无论如何它都不能为
NULL