我有一个简单的父子关系,我想使用LINQ to SQL加载。我想同时加载孩子和父母。生成的SQL做太多的工作。它正在努力计算孩子人数并加入他们的行列。我不会更新这些对象。我不会将孩子添加到父母中。我只对阅读感兴趣。我已经将表格简化到最低限度。实际上,我有更多列。 LINQ to SQL生成以下SQL
SELECT [t0].[parentId] AS [Id], [t0].[name], [t1].[childId] AS [Id2],
[t1].[parentId], [t1].[name] AS [name2],
( SELECT COUNT(*)
FROM [dbo].[linqchild] AS [t2]
WHERE [t2].[parentId] = [t0].[parentId]
) AS [value]
FROM [dbo].[linqparent] AS [t0]
LEFT OUTER JOIN [dbo].[linqchild] AS [t1] ON [t1].[parentId] = [t0].[parentId]
ORDER BY [t0].[parentId], [t1].[childId]
我不知道为什么
SELECT COUNT(*) ...
在那里。我宁愿它消失。父表和子表在生产中都将具有数百万行。额外的查询要花费大量时间。似乎没有必要。有没有办法使它消失?我也不确定ORDER BY
的来源。这些类看起来像这样。
[Table(Name = "dbo.linqparent")]
public class LinqParent
{
[Column(Name = "parentId", AutoSync = AutoSync.OnInsert, IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)]
public long Id { get; set; }
[ Column( Name = "name", CanBeNull = false ) ]
public string name { get; set; }
[Association(OtherKey = "parentId", ThisKey = "Id", IsForeignKey = true)]
public IEnumerable<LinqChild> Kids { get; set; }
}
[Table(Name = "dbo.linqchild")]
public class LinqChild
{
[Column(Name = "childId", AutoSync = AutoSync.OnInsert, IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)]
public long Id { get; set; }
[ Column( Name = "parentId", CanBeNull = false ) ]
public long parentId { get; set; }
[Column(Name = "name", CanBeNull = false)]
public string name { get; set; }
}
我正在使用类似以下内容的查询,生产中会有一个where子句和一个匹配的索引。
using (DataContext context = new DataContext(new DatabaseStringFinder().ConnectionString, new AttributeMappingSource()) { ObjectTrackingEnabled = false, DeferredLoadingEnabled = false })
{
var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<LinqParent>(f => f.Kids);
context.LoadOptions = loadOptions;
var table = context.GetTable<LinqParent>();
context.Log = Console.Out;
// do something with table.
}
最佳答案
很不幸的是,不行。 ORM从来都不是性能最高的解决方案。如果您编写自己的SQL(或使用存储过程),则始终会获得更好的性能,但这是所要做出的权衡。
您所看到的是ORM的标准做法;而不是使用多结果查询(在我看来这是最有效的方法,但我不是ORM库作者),ORM会将整个图展平为一个查询,并带回它需要的所有信息-包括有助于确定哪些数据重复的信息-来重建图表。
这也是ORDER BY
的来源,因为它要求链接的实体位于连续的块中。