我是否可以对 IQueryable 中的每个元素应用转换,并将结果作为 IQueryable



在我的 C# 应用程序中,我有一个返回 IQueryable 的方法,其中 MyClass 是实体框架代码优先的类。 它看起来像这样。

// Is a class for Entity Framework code-first
public class MyClass
{
    public int Id {get; set;}
    public int LuckyNumber {get; set;}
}
public IQueryable<MyClass> GetQuery()
{
    var query = doSomethingToGetQuery();
    return query;
}

假设我想创建一个返回 IQueryable 的方法,但我希望我的查询在返回数据之前对数据应用一些转换。

如果我有一个返回 IEnumerable 的方法,我可以写这样的东西:

public IEnumerable<MyClass> GetEnumerable()
{
    var query = doSomethingToGetQuery();
    return query.Select(x =>
    {
        var y = x;
        y.LuckyNumber = 2 * x.LuckyNumber;
        return y;
    }
}

因此,我会有一个 IEnumerable,它将返回与原始函数相同的数据,但它会使 LuckyNumber 翻倍。

假设我想做类似的事情,但我想返回一个 IQueryable,其中结果与查询原始查询相同,但在结果中,LuckyNumber 值加倍,或者应用了其他一些转换。

此外,我不想执行返回整个数据集的 SQL 查询,尤其是当我按 ID 检索单个记录时。

我可以在 C# 中执行此操作吗?

假设我想创建一个返回 IQueryable 的方法,但我希望我的查询在返回数据之前对数据应用一些转换。

确定。 您只需要调用 Queryable.Select,而不是 Enumerable.Select。 如果传递Func<TSource,TResult>则它将解析为对 Enumerable.Select 的调用,并且将在应用其他表达式之前执行查询。

但是,如果传递Expression<Func<TSource,TResult>>则重载将解析为 Queryable。Select,并且将修改查询,新投影将包装现有查询。

实现此目的的最简单方法是使用 LINQ。 例如:

public IQueryable<MyClass> GetEnumerable()
{
    IQueryable<MyClass> query = null; //whatever
    IQueryable<MyClass> q2 = 
             from m in query
             select new MyClass()
             {
                 LuckNumber = m.LuckNumber * 2
             };
    return q2;      
 }

请注意,如果这样做,您可能会破坏ORM编写有效查询的能力,该查询将谓词通过投影推送到基表。

最新更新