在我的 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编写有效查询的能力,该查询将谓词通过投影推送到基表。