Reputation: 1362
Consider this compiled linq-to-sql query:
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);
But I'm holding a private reference to context in the class already and I want to be able to mark the query as public without exposing the context e.g.
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.
Is there any way to do this without creating a public wrapper function for each query??
Upvotes: 4
Views: 1784
Reputation: 1499860
Is your reference to the context static, i.e. you've got a single context across the type? That doesn't sound like a great idea to me. Anyway, leaving that to one side, you can do:
// 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);
EDIT: Okay, if you don't like this approach, you could try writing your own generic wrappers around CompiledQuery.Compile
instead. For example:
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);
}
}
(And so on for more parameters.)
I haven't tried even compiling that, but I think it will work. You'd then use it like this:
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);
It's still creating a wrapper of course, but at least you only need to do it in one place. If your objection to creating wrappers was anything other than the tedium/code mess of it, please give more details.
Upvotes: 3