c# - Linq 在不传递上下文的情况下编译查询

标签 c# linq linq-to-sql precompiled

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

相关文章:

c# - 服务层还是 Controller ?

c# - Donut 二维空间的二进制空间分区数据结构

c# - IEnumerable<T> 是否替换了糟糕的设计?

没有主键的 Linq 插入

asp.net - 划分 Linq to SQL 查询

c# - 如何使用 LINQ for CRUD 和一个简单的 SQL 表?

c# - 如何使用 TFS build 2015 运行自动 selenium 测试?

c# - 用于限制可以为属性设置的值的结构化代码

c# - 如何在不影响性能的情况下执行 LINQ GroupBy、Select 和 Take?

c# - 搜索 - IQueryable Linq