考虑这个已编译的 linq-to-sql 查询:
private static Func<LINQDBDataContext, string, IQueryable<Pet>>
QueryFindByName =
CompiledQuery.Compile((
MyLinqDataContext context, string name) =>
from p in context.Pets where p.Name == name select p);
但是我已经在类中持有对上下文的私有(private)引用,我希望能够将查询标记为公开而不暴露上下文,例如
private static MyLinqDataContext context = SomeUtilityClass.GetMeMyContext();
//...
public static Func<string, IQueryable<Pet>> QueryFindByName =
CompiledQuery.Compile((string name) =>
from p in this.context.Pets where p.Name == name select p);
//doesn't compile as expects TArg0 to be a DataContext.
有没有办法在不为每个查询创建公共(public)包装函数的情况下做到这一点?
最佳答案
您对上下文的引用是静态的,即您在整个类型中有一个上下文吗?对我来说,这听起来不是个好主意。无论如何,将其放在一边,您可以:
// Private version which takes a context...
private static Func<LINQDBDataContext, string, IQueryable<Pet>>
QueryFindByNameImpl =
CompiledQuery.Compile((
LINQDBDataContext context, string name) =>
from p in context.Pets where p.Name == name select p);
// Public version which calls the private one, passing in the known context
public static Func<string, IQueryable<Pet>> QueryFindByName =
name => QueryFindByNameImpl(contextFromType, name);
编辑:好的,如果您不喜欢这种方法,您可以尝试围绕 CompiledQuery.Compile
编写您自己的通用包装器。例如:
public static class LinqHelpers
{
public static Func<TArg0, TResult> Compile<TContext, TArg0, TResult>
(this TContext context,
Expression<Func<TContext, TArg0, TResult>> query)
where TContext : DataContext
{
Func<TContext, TArg0, TResult> compiled =
CompiledQuery.Compile(query);
return arg => compiled(context, arg);
}
}
(以此类推更多参数。)
我什至没有尝试编译它,但我认为它会起作用。然后你会像这样使用它:
private static MyLinqDataContext context = SomeUtilityClass.GetMeMyContext();
public static Func<string, IQueryable<Pet>> QueryFindByName = context.Compile
((LINQDBDataContext context, string name) =>
from p in context.Pets where p.Name == name select p);
当然它仍然在创建一个包装器,但至少你只需要在一个地方做它。如果您反对创建包装器不是因为它乏味/代码困惑,请提供更多详细信息。
关于c# - Linq 在不传递上下文的情况下编译查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/561853/