我正在尝试阅读此链接:
https://stackoverflow.com/a/5971677
用于在SSDL中定义自定义函数。然而,从外观上看,自定义函数似乎是有限的,并且可以接受原始类型的输入参数。如何将IQueryable类型作为输入参数传递?
上面的链接显示了Double.Parse的简单自定义功能。但我需要更多的功能。
您可以通过linq表达式树和扩展方法来实现:
public static IQueryable<TSource> FilterConfirmable<TSource>(this IQueryable<TSource> source, ConfirmableFilter Confirmablefilter, [Optional, DefaultParameterValue("Confirmed")] string fieldName)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (Confirmablefilter == ConfirmableFilter.All)
{
return source;
}
Type sourceType = typeof(TSource);
PropertyInfo confirmedProperty = sourceType.GetProperty(fieldName);
if (confirmedProperty == null)
{
throw new InvalidOperationException(string.Format("Can not find a boolean column named "{0}", Consider to add a column named "{0}" in your linq select expression.", fieldName));
}
ParameterExpression o = Expression.Parameter(sourceType, "o");
Expression equal = Expression.Equal(Expression.Property(o, confirmedProperty), Expression.Constant(Confirmablefilter == ConfirmableFilter.Confirmed));
MethodCallExpression whereCallExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { sourceType }, new Expression[] { source.Expression, Expression.Lambda<Func<TSource, bool>>(equal, new ParameterExpression[] { o }) });
return source.Provider.CreateQuery<TSource>(whereCallExpression);
}
并像这样使用:
q = from i in ctx.persons select i;
q = q.FilterConfirmable(...).where(...);