【发布时间】:2014-01-31 03:48:09
【问题描述】:
我想为 IQueryable 创建我的自定义表达式。示例扩展方法:
public static IQueryable<T> GetByIntTest<T>(this IQueryable<T> qSource, Expression<Func<T, int?>> field, int? value)
{
if (value == null)
return qSource;
ConstantExpression constantExpression = Expression.Constant(value, typeof(int?));
BinaryExpression binaryExpression = Expression.Equal(field.Body, constantExpression);
var predicate = Expression.Lambda<Func<T, bool>>(binaryExpression, field.Parameters);
return qSource.Where(predicate);
}
它可以工作,但问题是它转换为未参数化的 sql。
例如没有扩展名的代码
int userId = 3;
var testUsual = Context.Set<User>().Where(u => u.Id == userId);
翻译成下一条sql
SELECT [Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
FROM [dbo].[User] AS [Extent1]
WHERE [Extent1].[Id] = @p__linq__0
及扩展方法
int userId = 3;
var testExtension = Context.Set<User>().GetByIntTest(u => u.Id, userId);
翻译成
SELECT [Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
FROM [dbo].[User] AS [Extent1]
WHERE 3 = [Extent1].[Id]
那么我该如何编写表达式以在 sql 中生成类似 @p_linq_0 的内容?
更新
感谢usr的回答,我重写了我的扩展方法,现在它生成了我想要的@p_linq_0。
public static IQueryable<T> GetByIntTest<T>(this IQueryable<T> qSource, Expression<Func<T, int?>> field, int? value)
{
if (value == null)
return qSource;
var binaryExpression = Expression.Equal(field.Body, ExpressionClosureFactory.GetField(value));
var predicate = Expression.Lambda<Func<T, bool>>(binaryExpression, field.Parameters);
return qSource.Where(predicate);
}
public class ExpressionClosureFactory
{
public static MemberExpression GetField<TValue>(TValue value)
{
var closure = new ExpressionClosureField<TValue>
{
ValueProperty = value
};
return Expression.Field(Expression.Constant(closure), "ValueProperty");
}
class ExpressionClosureField<T>
{
public T ValueProperty;
}
}
【问题讨论】:
标签: c# linq-to-sql expression expression-trees iqueryable