我正在使用LINQ提供程序,因此我正在实现IQueryable。
此界面中Expression
属性的用途是什么?我通常会从我的实现中返回类似Expression.Constant(this)
的内容,但不知道这是不是很糟糕。
奇怪的是documentation状态"这允许框架区分LINQ和实体SQL查询"。
答案 0 :(得分:4)
IQueryable.Expression
成员被所有各种IQueryProvider
"运营商"反馈给Queryable.*
。 (.Where()
,.Select()
,.Join()
,...),如:
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) {
if (source == null)
throw Error.ArgumentNull("source");
if (predicate == null)
throw Error.ArgumentNull("predicate");
return source.Provider.CreateQuery<TSource>(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
new Expression[] { source.Expression, Expression.Quote(predicate) }
));
}
(摘自referencesource)
通常它应该是整个表达式。
如果你通过IQueryable
直接传递了Expression.Constant()
课程的完整参考资料,显然没有人会杀了你,但我确实认为这不是&#34;#34; kosher&#34 ;。
关注&#34;真实&#34; Expression
中的表达式(就像它由Enumerable.AsQueryable()
,由EF和LINQ-to-SQL完成,只是为了命名三个IQueryable
提供者)是其他外部类可以自由分析和操纵Expression
并以与Queryable.Where
相同的方式将其反馈给提供者,这样做
Expression expression = source.Expression;
// here "expression" is manipulated
return source.Provider.CreateQuery<SomeType>(expression);
举个例子......有一些&#34;查询修复程序可以修改查询,如https://github.com/davidfowl/QueryInterceptor(查询的通用修饰符)或https://github.com/hazzik/DelegateDecompiler,允许要做:
var employees = (from employee in db.Employees
where employee.FullName == "Test User"
select employee).Decompile().ToList();
其中FullName
不是在数据库中映射,并且属性如下:
class Employee
{
[Computed]
public string FullName
{
get { return FirstName + " " + LastName; }
}
(FirstName
和LastName
映射到数据库)。 DelegateDecompiler 从Expression
获取IQueryable
,搜索具有Computed
属性的属性,对其进行反编译并放置反编译代码(转换为表达式树)回到IQueryable.Expression
(虽然使用IQueryable.Provider.CreateQuery()
)
如果您想保存其他数据,可以将其放在Provider
中:您可以在IQueryProvider
方法中生成CreateQuery
类的新实例。这也是由Queryable.*
运算符反馈的(因为CreateQuery<>
是source.Provider
的实例方法)