考虑这个编译的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 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.
有没有办法在不为每个查询创建公共包装函数的情况下执行此操作?
答案 0 :(得分:3)
您对上下文的引用是否是静态的,即您在该类型中有一个单独的上下文?这对我来说听起来不是一个好主意。无论如何,把它留在一边,你可以做到:
// 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);
当然,它仍在创建一个包装器,但至少你只需要在一个地方完成它。如果您对创建包装器的反对意见不是单调乏味/代码混乱,请提供更多详细信息。