有什么方法可以在执行之后/期间延迟对 IQueryable<T> 执行委托?

Jas*_*ker 5 c# linq delegates linq-to-sql

我从我的业务层公开了一个 IQueryable 方法,以便在其他层中使用。一旦查询在下层执行,我想对枚举中的每个项目执行一个函数。

似乎应该在查询执行后引发一个事件,以便我可以对这个公共层的结果进行操作。

就像是:

public IQueryable<User> Query() 
{
    return _Repository.Query<User>().ForEachDelayed(u=> AppendData(u));
}
Run Code Online (Sandbox Code Playgroud)

我希望 ForEachDelayed 函数在不执行查询的情况下返回 IQueryable。这个想法是,一旦执行查询,结果就会通过这个委托传递。

有这样的东西吗?如果没有,是否有我可以订阅的“IQueryable.OnExecute”之类的事件?

任何帮助都会很棒 - 谢谢!

编辑:

我以为我有这个答案:

var users = from u in _Repository.Query<User>()
            select AppendData(u);
return users;
Run Code Online (Sandbox Code Playgroud)

但是现在,我收到以下错误:

方法“AppendData(User)”不支持转换为 SQL。

我真的需要一个委托来在查询执行后运行。

sma*_*ell 1

简单的方法

另一个更简单的选项是使用 附加您需要的内容Iterator,请参阅下面的示例。这种方法的缺点是,在执行迭代时,所有内容都会被拉入内存,因此AppendData仅对返回的数据执行。这与 @Chris 的选项类似,但您不必在每次想要使用该方法时都被迫创建一个新的查询FuncSelect

static void Main(string[] args)
{
    var data = new List<int> { 1, 2, 3, 4, 5 }.AsQueryable().AppendData();

    Console.WriteLine("Before execute");

    Console.Write("{ ");
    foreach (var x in data)
       Console.Write("{0}, ", x);

    Console.WriteLine( "}");

    Console.WriteLine("After execute");

    Console.Read();
}

// Append extra data. From this point on everything is in memory
// This should be generic, i.e. AppendData<T>, but I an easy way to "append"
static IEnumerable<int> AppendData(this IEnumerable<int> data)
{
    Console.WriteLine("Adding");
    foreach (var x in data)            
        yield return x * 2;
}
Run Code Online (Sandbox Code Playgroud)

艰难的道路

我不相信有任何像这样的内置事件,但您可能可以通过实现自己的IQueryable包装器来添加自己的事件。

是一个关于编写完整的提供程序的系列IQueryable,它还将向您展示可以在哪里安装您的包装器,最有可能围绕它IQueryProvider

祝你好运,希望这能帮到你。