C# 已编译的LINQ查询和数据加载选项。。。转一转!
我知道这里讨论的方法: 。。。但这不适合我的情况,因为我得到了: 从查询返回结果后,不允许设置加载选项 我正在使用Codesmith PLINQO脚本生成实体和管理器代码,管理器代码如下所示:C# 已编译的LINQ查询和数据加载选项。。。转一转!,c#,linq,compiled-query,loadoptions,C#,Linq,Compiled Query,Loadoptions,我知道这里讨论的方法: 。。。但这不适合我的情况,因为我得到了: 从查询返回结果后,不允许设置加载选项 我正在使用Codesmith PLINQO脚本生成实体和管理器代码,管理器代码如下所示: public partial class SearchManager { #region Query // A private class for lazy loading static compiled queries. private static partial
public partial class SearchManager
{
#region Query
// A private class for lazy loading static compiled queries.
private static partial class Query
{
internal static readonly Func<MyDataContext,IOrderedQueryable<Search>>
GetAll = CompiledQuery.Compile(
(MyDataContext db) =>
from s in db.Search
orderby s.Name
select s);
}
#endregion
public IQueryable<Search> GetAll()
{
return Query.GetAll(Context);
}
}
public static readonly DataLoadOptions MyOptions =
(new Func<DataLoadOptions>(() =>
{
var option = new DataLoadOptions();
option.LoadWith<Search>(x => x.Rule);
return option;
}))();
我首先尝试将静态DataLoadOptions放入Searchmanager类,如下所示:
public partial class SearchManager
{
#region Query
// A private class for lazy loading static compiled queries.
private static partial class Query
{
internal static readonly Func<MyDataContext,IOrderedQueryable<Search>>
GetAll = CompiledQuery.Compile(
(MyDataContext db) =>
from s in db.Search
orderby s.Name
select s);
}
#endregion
public IQueryable<Search> GetAll()
{
return Query.GetAll(Context);
}
}
public static readonly DataLoadOptions MyOptions =
(new Func<DataLoadOptions>(() =>
{
var option = new DataLoadOptions();
option.LoadWith<Search>(x => x.Rule);
return option;
}))();
。。。然后在GetAll方法中将其提供给上下文,如下所示:
public IQueryable<Search> GetAll()
{
Context.LoadOptions = MyOptions;
return Query.GetAll(Context);
}
…这给了我上面提到的错误。这是因为查询已编译,因此无法添加额外的DataLoadOptions吗?如果是这样,在编译查询之前如何应用DataLoadOptions?错误消息本身会准确地告诉您错误所在。Linq查询返回结果后,无法应用DataLoadOptions。或者,也许更好的说法如下。如果要应用DataLoadOptions,请在执行查询之前应用。以后不能这样做。对于已编译的查询,只能设置一次加载选项。必须在第二次调用时抛出错误。将赋值移到一个静态构造函数,这样应该可以解决您的问题
public IQueryable<Search> GetAll() {
Context.LoadOptions = MyOptions;
return Query.GetAll(Context);
}
如果上下文已返回任何查询结果,则此分配太迟。这与已编译的查询无关,与分配DataContext的LoadOptions属性有关。不幸的是,LoadOptions属性的这种行为没有记录在msdn上。在DataContext类的setter属性中,有一个条件检查DataContext的缓存中是否有任何对象,LoadOptions不为null,并且您尝试设置的LoadOptions实例与已设置的实例不同,然后你会得到这个例外 备选案文1。为每个查询创建一个新的上下文可能不是一个好主意 备选案文2。使用反射调用ClearCache方法,然后静态地创建一个新的LoadOptions,将其分配给上下文,最后获取已编译的查询
public partial class SearchManager
{
#region Query
// A private class for lazy loading static compiled queries.
private static partial class Query
{
internal static readonly Func<MyDataContext,IOrderedQueryable<Search>> GetAll
{
get {
return CompiledQuery.Compile(
(MyDataContext db) =>
from s in db.Search
orderby s.Name
select s);
}
}
#endregion
public IQueryable<Search> GetAll()
{
Context.ClearCache();
Context.LoadOptions = MyOptions;
return Query.GetAll(Context);
}
public static readonly DataLoadOptions MyOptions =
(new Func<DataLoadOptions>(() => MakeLoadOptions<Search>(x=>x.Rule)))();
}
public static class Extensions {
public static void ClearCache(this DataContext context)
{
const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
var method = context.GetType().GetMethod("ClearCache", FLAGS);
method.Invoke(context, null);
}
public static DataLoadOptions MakeLoadOptions<TEntity, TResult>(this Expression<Func<TEntity,TResult>> func) {
DataLoadOptions options = new DataLoadOptions();
options.LoadWith(func);
return options;
}
}
实际上,错误发生在调用查询之前,如图所示:public IQueryable GetAll{Context.LoadOptions=MyOptions;return query.GetAllContext;}检查发布的答案,如果您得到了所需的信息,请接受它