4

考虑这个编译的 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.

有没有办法在不为每个查询创建公共包装函数的情况下做到这一点?

4

1 回答 1

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);

当然,它仍在创建一个包装器,但至少你只需要在一个地方完成它。如果您反对创建包装器不是因为它的乏味/代码混乱,请提供更多详细信息。

于 2009-02-18T16:42:42.093 回答