Pau*_*aul 6 c# performance linq-to-sql
我正在将LINQ to SQL结果投射到强类型类:Parent和Child.这两个查询之间的性能差异很大:
慢查询 - 从DataContext记录显示正在为每个父级单独调用db
var q = from p in parenttable
select new Parent()
{
id = p.id,
Children = (from c in childtable
where c.parentid = p.id
select c).ToList()
}
return q.ToList() //SLOW
Run Code Online (Sandbox Code Playgroud)
快速查询 - 从DataContext进行日志记录显示单个数据库命中查询,该查询返回所有必需数据
var q = from p in parenttable
select new Parent()
{
id = p.id,
Children = from c in childtable
where c.parentid = p.id
select c
}
return q.ToList() //FAST
Run Code Online (Sandbox Code Playgroud)
我想强制LINQ使用第二个示例的单一查询样式,但直接用Parent对象填充Parent类.否则,IQuerierable<Child>必须查询Children属性以公开Child对象.
引用的问题似乎并不能解决我的情况.使用db.LoadOptions不起作用.也许它要求类型是在DataContext中注册的TEntity.
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Parent>(p => p.Children);
db.LoadOptions = options;
Run Code Online (Sandbox Code Playgroud)
请注意:父和子是简单类型,而不是Table<TEntity>类型.父母与子女之间没有语境关系.子查询是临时的.
问题的症结:在第二个LINQ示例中,我实现IQueriable语句而不调用ToList()函数,由于某种原因,LINQ知道如何生成一个可以检索所有必需数据的单个查询.如何使用第一个查询中完成的实际数据填充我的临时投影?此外,如果有人能帮助我更好地表达我的问题,我将不胜感激.
重要的是要记住LINQ查询依赖于延迟执行.在第二个查询中,您实际上并未获取有关子项的任何信息.您已经创建了查询,但实际上并没有执行它们来获取这些查询的结果.如果您要迭代列表,然后迭代Children每个项目的集合,您会看到它花费的时间与第一个查询一样多.
您的查询本身也非常低效.您正在使用嵌套查询来表示Join关系.如果使用a Join,则查询提供程序和数据库都可以适当地优化查询,以便更快地执行.您可能还需要调整数据库上的索引以提高性能.以下是连接的外观:
var q = from p in parenttable
join child in childtable
on p.id equals child.parentid into children
select new Parent()
{
id = p.id,
Children = children.ToList(),
}
return q.ToList() //SLOW
Run Code Online (Sandbox Code Playgroud)
您必须为数据加载设置正确的选项。
options.LoadWith<Document>(d => d.Metadata);
Run Code Online (Sandbox Code Playgroud)
看这个
PSInclude仅供参考LINQToEntity。