【发布时间】:2009-08-03 18:07:31
【问题描述】:
我们发现compiling our Linq queries 比他们每次都编译要快得多,所以我们想开始使用编译查询。问题是它使代码更难阅读,因为查询的实际语法在其他文件中是关闭的,远离它的使用位置。
我突然想到,可能可以编写一个方法(或扩展方法),使用反射来确定传入的查询并自动缓存已编译的版本以供将来使用。
var foo = (from f in db.Foo where f.ix == bar select f).Cached();
Cached() 必须反映传入的查询对象并确定选择的表和查询的参数类型。显然,反射有点慢,所以最好为缓存对象使用名称(但您仍然必须在第一次编译查询时使用反射)。
var foo = (from f in db.Foo where f.ix == bar select f).Cached("Foo.ix");
有没有人有这方面的经验,或者知道这是否可能?
更新:没看过的可以用下面的代码编译LINQ查询to SQL:
public static class MyCompiledQueries
{
public static Func<DataContext, int, IQueryable<Foo>> getFoo =
CompiledQuery.Compile(
(DataContext db, int ixFoo) => (from f in db.Foo
where f.ix == ixFoo
select f)
);
}
我想要做的是缓存这些Func<> 对象,我可以在第一次自动编译查询后调用这些对象。
【问题讨论】:
-
这是一个令人困惑的问题,因为您似乎将 LINQ 和 LINQ to SQL 混为一谈(每次运行查询时,它都会在后台额外生成、编译和缓存执行计划)。如果您询问 SQL Server 的已编译执行计划,那么(据我所知)除了运行它们之外,无法编译它们并保持缓存。
-
这与 SQL Server 无关。每次运行这些查询时,LINQ to SQL 都会从两种 LINQ 语法(链式或 SQL 样式)编译查询(这可能需要相当长的时间)到 SQL。阅读顶部的链接以了解更多信息。
-
我在 Web 应用程序中使用 L2S 编译查询时发现的一个问题是,要编译它,您需要将 DataContext 的实例传递给它 - 对于 Web 应用程序,这意味着您需要一个共享整个站点的 DataContext - 当站点开始有大负载时,这反过来给我带来了一些主要的多线程问题。我真的很不喜欢在编译查询时必须传递 datacontext 实例...
-
编译查询时不传入 DataContext。请参阅下面的答案;你实际上传入了一个委托,它接受一个 DataContext(和其他参数)并返回一个
IQueryable<T>。 -
你有没有实现过这条路径?如果是这样,您是如何处理不同的 DataLoadOptions 的?
标签: c# asp.net-mvc linq linq-to-sql iqueryable