我有一个简单的类来表示树结构,定义如下:
public class LicenceCategory
{
[Key]
[Column("LicenceCategoryID")]
public Guid ID { get; set; }
public string Name { get; set; }
public Guid? ParentLicenceCategoryID { get; set; }
[ForeignKey("ParentLicenceCategoryID")]
public virtual List<LicenceCategory> Categories { get; set; }
}
然后,从ASP.NET Core控制器中,我简单地返回myContext.LicenceCategory
,它变得非常简单。
现在,数据库上有5条记录:父级(空ParentLicenceCategoryID
)和该父级的四个子级。因此,没有大量的内容,也没有非常深的嵌套。这是生成的SQL,与我期望的一样:
SELECT [obj].[LicenceCategoryID], [obj].[Name], [obj].[ParentLicenceCategoryID]
FROM [LicenceCategory] AS [obj]
但是,它也会生成五次:
SELECT [e].[LicenceCategoryID], [e].[Name], [e].[ParentLicenceCategoryID]
FROM [LicenceCategory] AS [e]
WHERE [e].[ParentLicenceCategoryID] = @__get_Item_0
请注意第一条语句已经包含了构建客户端树状结构所需的每个字段。到底为什么还要使用额外的select语句?
我注意到,如果我使用Include
导航属性,情况会变得更糟:对于三个导航属性,我最终获得了21条select语句!其中大多数只是一次又一次执行的同一条语句。它可能使用不同的参数来执行此操作,但是几乎没有任何方法可以使程序的效率降低。这是五个记录-当我将数百万笔交易记录扔掉时,EF会怎么做?
是否有一种方法可以防止这种代码的生成,或者EF Core只是一个入门者?