Ответ 1
Что-то вроде:
static void Main() {
using(var ctx= new DataClasses1DataContext()) {
ctx.Log = Console.Out;
var qry = ctx.Customers.WhereLike("CompanyName", "a%s");
Console.WriteLine(qry.Count());
}
}
static IQueryable<T> WhereLike<T>(this IQueryable<T> source,
string propertyOrFieldName, string pattern) {
var param = Expression.Parameter(typeof(T), "row");
var body = Expression.Call(
null,
typeof(SqlMethods).GetMethod("Like",
new[] { typeof(string), typeof(string) }),
Expression.PropertyOrField(param, propertyOrFieldName),
Expression.Constant(pattern, typeof(string)));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
return source.Where(lambda);
}
static IQueryable<T> WhereLike<T>(this IQueryable<T> source,
string propertyOrFieldName, string pattern, char escapeCharacter) {
var param = Expression.Parameter(typeof(T), "row");
var body = Expression.Call(
null,
typeof(SqlMethods).GetMethod("Like",
new[] { typeof(string), typeof(string), typeof(char) }),
Expression.PropertyOrField(param, propertyOrFieldName),
Expression.Constant(pattern, typeof(string)),
Expression.Constant(escapeCharacter,typeof(char)));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
return source.Where(lambda);
}
Вы также можете подумать о том, чтобы сделать его более многоразовым:
static void Main() {
using(var ctx= new DataClasses1DataContext()) {
ctx.Log = Console.Out;
var qry1 = ctx.Customers.WhereInvoke<Customer, string>(
"CompanyName", s => s.Contains("abc"));
Console.WriteLine(qry1.Count());
var qry2 = ctx.Customers.WhereInvoke<Customer, string>(
"CompanyName", s => s.StartsWith("abc"));
Console.WriteLine(qry2.Count());
var qry3 = ctx.Customers.WhereInvoke<Customer, string>(
"CompanyName", s => s.EndsWith("abc"));
Console.WriteLine(qry3.Count());
}
}
static IQueryable<TSource> WhereInvoke<TSource, TValue>(
this IQueryable<TSource> source,
string propertyOrFieldName,
Expression<Func<TValue, bool>> func) {
var param = Expression.Parameter(typeof(TSource), "row");
var prop = Expression.PropertyOrField(param, propertyOrFieldName);
if(prop.Type != typeof(TValue)) {
throw new InvalidOperationException("The property must be " + typeof(TValue).Name);
}
var body = Expression.Invoke(func, prop);
var lambda = Expression.Lambda<Func<TSource, bool>>(body, param);
return source.Where(lambda);
}